#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 <sys/ioctl.h>
#include "asterisk/dahdi_compat.h"
#include "asterisk/lock.h"
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/config.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/translate.h"
#include "asterisk/md5.h"
#include "asterisk/cdr.h"
#include "asterisk/crypto.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/app.h"
#include "asterisk/astdb.h"
#include "asterisk/musiconhold.h"
#include "asterisk/features.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/localtime.h"
#include "asterisk/aes.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/netsock.h"
#include "asterisk/stringfields.h"
#include "asterisk/linkedlists.h"
#include "asterisk/astobj2.h"
#include "iax2.h"
#include "iax2-parser.h"
#include "iax2-provision.h"
#include "jitterbuf.h"
Go to the source code of this file.
Data Structures | |
struct | active_list |
struct | ast_firmware_list |
struct | ast_iax2_queue |
struct | chan_iax2_pvt |
struct | create_addr_info |
struct | dpreq_data |
struct | dynamic_list |
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 | idle_list |
struct | parsed_dial_string |
struct | registrations |
Defines | |
#define | CACHE_FLAG_CANEXIST (1 << 2) |
#define | CACHE_FLAG_EXISTS (1 << 0) |
#define | CACHE_FLAG_MATCHMORE (1 << 7) |
#define | CACHE_FLAG_NONEXISTENT (1 << 1) |
#define | CACHE_FLAG_PENDING (1 << 3) |
#define | CACHE_FLAG_TIMEOUT (1 << 4) |
#define | CACHE_FLAG_TRANSMITTED (1 << 5) |
#define | CACHE_FLAG_UNKNOWN (1 << 6) |
#define | CALLNO_TO_PTR(a) ((void *)(unsigned long)(a)) |
#define | DEBUG_SCHED_MULTITHREAD |
#define | DEBUG_SUPPORT |
#define | DEFAULT_DROP 3 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_THREAD_COUNT 100 |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_RETRY_TIME 1000 |
#define | DEFAULT_THREAD_COUNT 10 |
#define | DEFAULT_TRUNKDATA 640 * 10 |
#define | FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s\n" |
#define | FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
#define | FORMAT "%-15.15s %-15d %-15d\n" |
#define | FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" |
#define | FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
#define | FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" |
#define | FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
#define | FORMAT2 "%-15.15s %-15.15s %-15.15s\n" |
#define | FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" |
#define | FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
#define | FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
#define | GAMMA (0.01) |
#define | IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
#define | IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
#define | IAX_CAPABILITY_LOWBANDWIDTH |
#define | IAX_CAPABILITY_LOWFREE |
#define | IAX_CAPABILITY_MEDBANDWIDTH |
#define | IAX_IOSTATE_IDLE 0 |
#define | IAX_IOSTATE_PROCESSING 2 |
#define | IAX_IOSTATE_READY 1 |
#define | IAX_IOSTATE_SCHEDREADY 3 |
#define | IAX_TYPE_DYNAMIC 2 |
#define | IAX_TYPE_POOL 1 |
#define | IPTOS_MINCOST 0x02 |
#define | MAX_JITTER_BUFFER 50 |
#define | MAX_PEER_BUCKETS 1 |
#define | MAX_RETRY_TIME 10000 |
#define | MAX_TIMESTAMP_SKEW 160 |
#define | MAX_TRUNKDATA 640 * 200 |
#define | MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define | MEMORY_SIZE 100 |
#define | MIN_JITTER_BUFFER 10 |
#define | MIN_RETRY_TIME 100 |
#define | MIN_REUSE_TIME 60 |
#define | NEW_ALLOW 1 |
#define | NEW_FORCE 2 |
#define | NEW_PREVENT 0 |
#define | PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a)) |
#define | SCHED_MULTITHREADED |
#define | schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__) |
#define | TRUNK_CALL_START ARRAY_LEN(iaxs) / 2 |
#define | TS_GAP_FOR_JB_RESYNC 5000 |
Enumerations | |
enum | { IAX_STATE_STARTED = (1 << 0), IAX_STATE_AUTHENTICATED = (1 << 1), IAX_STATE_TBD = (1 << 2), IAX_STATE_UNCHANGED = (1 << 3) } |
enum | { IAX_HASCALLERID = (1 << 0), IAX_DELME = (1 << 1), IAX_TEMPONLY = (1 << 2), IAX_TRUNK = (1 << 3), IAX_NOTRANSFER = (1 << 4), IAX_USEJITTERBUF = (1 << 5), IAX_DYNAMIC = (1 << 6), IAX_SENDANI = (1 << 7), IAX_ALREADYGONE = (1 << 9), IAX_PROVISION = (1 << 10), IAX_QUELCH = (1 << 11), IAX_ENCRYPTED = (1 << 12), IAX_KEYPOPULATED = (1 << 13), IAX_CODEC_USER_FIRST = (1 << 14), IAX_CODEC_NOPREFS = (1 << 15), IAX_CODEC_NOCAP = (1 << 16), IAX_RTCACHEFRIENDS = (1 << 17), IAX_RTUPDATE = (1 << 18), IAX_RTAUTOCLEAR = (1 << 19), IAX_FORCEJITTERBUF = (1 << 20), IAX_RTIGNOREREGEXPIRE = (1 << 21), IAX_TRUNKTIMESTAMPS = (1 << 22), IAX_TRANSFERMEDIA = (1 << 23), IAX_MAXAUTHREQ = (1 << 24), IAX_DELAYPBXSTART = (1 << 25), IAX_ALLOWFWDOWNLOAD = (1 << 26) } |
enum | iax_reg_state { REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH } |
enum | iax_transfer_state { TRANSFER_NONE = 0, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED, TRANSFER_PASSTHROUGH, TRANSFER_MBEGIN, TRANSFER_MREADY, TRANSFER_MRELEASED, TRANSFER_MPASSTHROUGH, TRANSFER_MEDIA, TRANSFER_MEDIAPASS } |
Functions | |
static void | __attempt_transmit (const void *data) |
static void | __auth_reject (const void *nothing) |
static void | __auto_congest (const void *nothing) |
static void | __auto_hangup (const void *nothing) |
static int | __do_deliver (void *data) |
static void | __expire_registry (const void *data) |
static int | __find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno) |
static void | __get_from_jb (const void *p) |
static void | __iax2_do_register_s (const void *data) |
static void | __iax2_poke_noanswer (const void *data) |
static void | __iax2_poke_peer_s (const void *data) |
static int | __iax2_show_peers (int manager, int fd, struct mansession *s, int argc, char *argv[]) |
static void | __reg_module (void) |
static int | __schedule_action (void(*func)(const void *data), const void *data, const char *funcname) |
static int | __send_command (struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, int now, int transfer, int final) |
static void | __send_lagrq (const void *data) |
static void | __send_ping (const void *data) |
static int | __unload_module (void) |
static void | __unreg_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 int | attempt_transmit (const void *data) |
static int | auth_fail (int callno, int failcode) |
static int | auth_reject (const void *data) |
static int | authenticate (const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx) |
static int | authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey) |
static int | authenticate_request (int call_num) |
static int | authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies) |
static int | auto_congest (const void *data) |
static int | auto_hangup (const void *data) |
static struct iax2_context * | build_context (char *context) |
static void | build_enc_keys (const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx) |
static struct iax2_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
Create peer structure based on configuration. | |
static struct iax2_user * | build_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
Create in-memory user structure from configuration. | |
static int | cache_get_callno_locked (const char *data) |
static unsigned int | calc_rxstamp (struct chan_iax2_pvt *p, unsigned int offset) |
static unsigned int | calc_timestamp (struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f) |
static unsigned int | calc_txpeerstamp (struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv) |
static int | check_access (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
static int | check_provisioning (struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver) |
static int | check_srcaddr (struct sockaddr *sa, socklen_t salen) |
Check if address can be used as packet source. | |
static int | complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
static char * | complete_iax2_show_peer (const char *line, const char *word, int pos, int state) |
static int | complete_transfer (int callno, struct iax_ies *ies) |
static unsigned char | compress_subclass (int subclass) |
static void | construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) |
static int | create_addr (const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai) |
static int | decode_frame (aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
static int | decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
static void | defer_full_frame (struct iax2_thread *from_here, struct iax2_thread *to_here) |
Queue the last read full frame for processing by a certain thread. | |
static void | delete_users (void) |
static void | destroy_firmware (struct iax_firmware *cur) |
static void | dp_lookup (int callno, const char *context, const char *callednum, const char *callerid, int skiplock) |
static void * | dp_lookup_thread (void *data) |
static int | encrypt_frame (aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen) |
static int | expire_registry (const void *data) |
static struct iax2_dpcache * | find_cache (struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority) |
static int | find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) |
static int | find_callno_locked (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) |
static struct iax2_thread * | find_idle_thread (void) |
static struct iax2_peer * | find_peer (const char *name, int realtime) |
static struct iax2_trunk_peer * | find_tpeer (struct sockaddr_in *sin, int fd) |
static unsigned int | fix_peerts (struct timeval *tv, int callno, unsigned int ts) |
static void | free_context (struct iax2_context *con) |
static int | function_iaxpeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
static int | get_auth_methods (char *value) |
static int | get_encrypt_methods (const char *s) |
static int | get_from_jb (const void *p) |
static void | handle_deferred_full_frames (struct iax2_thread *thread) |
Handle any deferred full frames for this thread. | |
static int | handle_error (void) |
static int | iax2_ack_registry (struct iax_ies *ies, struct sockaddr_in *sin, int callno) |
Acknowledgment received for OUR registration. | |
static int | iax2_answer (struct ast_channel *c) |
static enum ast_bridge_result | iax2_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
static int | iax2_call (struct ast_channel *c, char *dest, int timeout) |
static int | iax2_canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
part of the IAX2 dial plan switch interface | |
static unsigned int | iax2_datetime (const char *tz) |
static void | iax2_destroy (int callno) |
static void | iax2_destroy_helper (struct chan_iax2_pvt *pvt) |
static int | iax2_devicestate (void *data) |
Part of the device state notification system ---. | |
static int | iax2_digit_begin (struct ast_channel *c, char digit) |
static int | iax2_digit_end (struct ast_channel *c, char digit, unsigned int duration) |
static int | iax2_do_debug (int fd, int argc, char *argv[]) |
static int | iax2_do_jb_debug (int fd, int argc, char *argv[]) |
static int | iax2_do_register (struct iax2_registry *reg) |
static int | iax2_do_register_s (const void *data) |
static int | iax2_do_trunk_debug (int fd, int argc, char *argv[]) |
static void | iax2_dprequest (struct iax2_dpcache *dp, int callno) |
static int | iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Execute IAX2 dialplan switch. | |
static int | iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Part of the IAX2 switch interface. | |
static int | iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan) |
static void | iax2_frame_free (struct iax_frame *fr) |
static int | iax2_getpeername (struct sockaddr_in sin, char *host, int len) |
static int | iax2_getpeertrunk (struct sockaddr_in sin) |
static int | iax2_hangup (struct ast_channel *c) |
static int | iax2_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen) |
static int | iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Part of the IAX2 Switch interface. | |
static int | iax2_no_debug (int fd, int argc, char *argv[]) |
static int | iax2_no_jb_debug (int fd, int argc, char *argv[]) |
static int | iax2_no_trunk_debug (int fd, int argc, char *argv[]) |
static int | iax2_poke_noanswer (const void *data) |
static int | iax2_poke_peer (struct iax2_peer *peer, int heldcall) |
static int | iax2_poke_peer_cb (void *obj, void *arg, int flags) |
static int | iax2_poke_peer_s (const void *data) |
static int | iax2_predestroy (int callno) |
static void * | iax2_process_thread (void *data) |
static void | iax2_process_thread_cleanup (void *data) |
static int | iax2_prov_app (struct ast_channel *chan, void *data) |
static int | iax2_prov_cmd (int fd, int argc, char *argv[]) |
static char * | iax2_prov_complete_template_3rd (const char *line, const char *word, int pos, int state) |
static int | iax2_provision (struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force) |
static int | iax2_prune_realtime (int fd, int argc, char *argv[]) |
static int | iax2_queue_control_data (int callno, enum ast_control_frame_type control, const void *data, size_t datalen) |
Queue a control frame on the ast_channel owner. | |
static int | iax2_queue_frame (int callno, struct ast_frame *f) |
Queue a frame to a call's owning asterisk channel. | |
static int | iax2_queue_hangup (int callno) |
Queue a hangup frame on the ast_channel owner. | |
static struct ast_frame * | iax2_read (struct ast_channel *c) |
static int | iax2_register (char *value, int lineno) |
static int | iax2_reload (int fd, int argc, char *argv[]) |
static struct ast_channel * | iax2_request (const char *type, int format, void *data, int *cause) |
static int | iax2_sched_add (struct sched_context *con, int when, ast_sched_cb callback, const void *data) |
static int | iax2_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final) |
static int | iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen) |
static int | iax2_sendimage (struct ast_channel *c, struct ast_frame *img) |
static int | iax2_sendtext (struct ast_channel *c, const char *text) |
static int | iax2_setoption (struct ast_channel *c, int option, void *data, int datalen) |
static int | iax2_show_cache (int fd, int argc, char *argv[]) |
static int | iax2_show_channels (int fd, int argc, char *argv[]) |
static int | iax2_show_firmware (int fd, int argc, char *argv[]) |
static int | iax2_show_netstats (int fd, int argc, char *argv[]) |
static int | iax2_show_peer (int fd, int argc, char *argv[]) |
Show one peer in detail. | |
static int | iax2_show_peers (int fd, int argc, char *argv[]) |
static int | iax2_show_registry (int fd, int argc, char *argv[]) |
static int | iax2_show_stats (int fd, int argc, char *argv[]) |
static int | iax2_show_threads (int fd, int argc, char *argv[]) |
static int | iax2_show_users (int fd, int argc, char *argv[]) |
static int | iax2_start_transfer (unsigned short callno0, unsigned short callno1, int mediaonly) |
static int | iax2_test_losspct (int fd, int argc, char *argv[]) |
static int | iax2_transfer (struct ast_channel *c, const char *dest) |
static int | iax2_transmit (struct iax_frame *fr) |
static int | iax2_trunk_expired (struct iax2_trunk_peer *tpeer, struct timeval *now) |
static int | iax2_trunk_queue (struct chan_iax2_pvt *pvt, struct iax_frame *fr) |
static int | iax2_vnak (int callno) |
static int | iax2_write (struct ast_channel *c, struct ast_frame *f) |
static int | iax_check_version (char *dev) |
static void | iax_debug_output (const char *data) |
static void | iax_error_output (const char *data) |
static int | iax_firmware_append (struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc) |
static int | iax_park (struct ast_channel *chan1, struct ast_channel *chan2) |
static void * | iax_park_thread (void *stuff) |
static struct iax_frame * | iaxfrdup2 (struct iax_frame *fr) |
static void | insert_idle_thread (struct iax2_thread *thread) |
static void | jb_debug_output (const char *fmt,...) |
static void | jb_error_output (const char *fmt,...) |
static void | jb_warning_output (const char *fmt,...) |
static int | load_module (void) |
Load IAX2 module, load configuraiton ---. | |
static void | lock_both (unsigned short callno0, unsigned short callno1) |
static int | make_trunk (unsigned short callno, int locked) |
static int | manager_iax2_show_netstats (struct mansession *s, const struct message *m) |
static int | manager_iax2_show_peers (struct mansession *s, const struct message *m) |
static int | match (struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur, int check_dcallno) |
static void | memcpy_decrypt (unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx) |
static void | memcpy_encrypt (unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx) |
static void | merge_encryption (struct chan_iax2_pvt *p, unsigned int enc) |
static void * | network_thread (void *ignore) |
static struct chan_iax2_pvt * | new_iax (struct sockaddr_in *sin, const char *host) |
static void | parse_dial_string (char *data, struct parsed_dial_string *pds) |
Parses an IAX dial string into its component parts. | |
static int | peer_cmp_cb (void *obj, void *arg, int flags) |
static int | peer_delme_cb (void *obj, void *arg, int flags) |
static void | peer_destructor (void *obj) |
static int | peer_hash_cb (const void *obj, const int flags) |
static struct iax2_peer * | peer_ref (struct iax2_peer *peer) |
static int | peer_set_sock_cb (void *obj, void *arg, int flags) |
static int | peer_set_srcaddr (struct iax2_peer *peer, const char *srcaddr) |
Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found. | |
static int | peer_status (struct iax2_peer *peer, char *status, int statuslen) |
peer_status: Report Peer status in character string | |
static struct iax2_peer * | peer_unref (struct iax2_peer *peer) |
static void | poke_all_peers (void) |
static void | prune_peers (void) |
static void | prune_users (void) |
static int | pvt_cmp_cb (void *obj, void *arg, int flags) |
static void | pvt_destructor (void *obj) |
static int | pvt_hash_cb (const void *obj, const int flags) |
static int | raw_hangup (struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd) |
static struct iax2_peer * | realtime_peer (const char *peername, struct sockaddr_in *sin) |
static void | realtime_update_peer (const char *peername, struct sockaddr_in *sin, time_t regtime) |
static struct iax2_user * | realtime_user (const char *username, struct sockaddr_in *sin) |
static void | reg_source_db (struct iax2_peer *p) |
static void | register_peer_exten (struct iax2_peer *peer, int onoff) |
static int | register_verify (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
Verify inbound registration. | |
static int | registry_authrequest (int callno) |
static int | registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin) |
static char * | regstate2str (int regstate) |
static int | reload (void) |
static int | reload_config (void) |
static void | reload_firmware (int unload) |
static void | remove_by_peercallno (struct chan_iax2_pvt *pvt) |
static void | save_rr (struct iax_frame *fr, struct iax_ies *ies) |
static void * | sched_thread (void *ignore) |
static int | schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout) |
static int | scheduled_destroy (const void *vid) |
static int | send_apathetic_reply (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno) |
static int | send_command (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_final (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_immediate (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_locked (unsigned short callno, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_transfer (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int) |
static int | send_lagrq (const void *data) |
static int | send_packet (struct iax_frame *f) |
static int | send_ping (const void *data) |
static int | send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now) |
static int | set_config (char *config_file, int reload) |
Load configuration. | |
static void | set_config_destroy (void) |
static void | set_timing (void) |
static void | signal_condition (ast_mutex_t *lock, ast_cond_t *cond) |
static int | socket_process (struct iax2_thread *thread) |
static int | socket_read (int *id, int fd, short events, void *cbdata) |
static void | spawn_dp_lookup (int callno, const char *context, const char *callednum, const char *callerid) |
static int | start_network_thread (void) |
static void | stop_stuff (int callno) |
static void | store_by_peercallno (struct chan_iax2_pvt *pvt) |
static int | timing_read (int *id, int fd, short events, void *cbdata) |
static int | transmit_trunk (struct iax_frame *f, struct sockaddr_in *sin, int sockfd) |
static int | try_firmware (char *s) |
static int | try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
static int | uncompress_subclass (unsigned char csub) |
static void | unlink_peer (struct iax2_peer *peer) |
static int | unload_module (void) |
static void | unlock_both (unsigned short callno0, unsigned short callno1) |
static void | unwrap_timestamp (struct iax_frame *fr) |
static void | update_jbsched (struct chan_iax2_pvt *pvt) |
static void | update_max_nontrunk (void) |
static void | update_max_trunk (void) |
static int | update_packet (struct iax_frame *f) |
static int | update_registry (struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh) |
static int | user_cmp_cb (void *obj, void *arg, int flags) |
static int | user_delme_cb (void *obj, void *arg, int flags) |
static void | user_destructor (void *obj) |
static int | user_hash_cb (const void *obj, const int flags) |
static struct iax2_user * | user_ref (struct iax2_user *user) |
static struct iax2_user * | user_unref (struct iax2_user *user) |
static void | vnak_retransmit (int callno, int last) |
static int | wait_for_peercallno (struct chan_iax2_pvt *pvt) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, .reload = reload, } |
static char | accountcode [AST_MAX_ACCOUNT_CODE] |
static int | adsi = 0 |
static int | amaflags = 0 |
static const struct ast_module_info * | ast_module_info = &__mod_info |
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 ast_mutex_t | dpcache_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static int | global_rtautoclear = 120 |
static struct ast_flags | globalflags = { 0 } |
static int | iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH |
static int | iax2_encryption = 0 |
enum { ... } | iax2_flags |
int(*) | iax2_regfunk (const char *username, int onoff) = NULL |
static char | iax2_reload_usage [] |
enum { ... } | iax2_state |
static struct ast_switch | iax2_switch |
static struct ast_channel_tech | iax2_tech |
static char | iax2_test_losspct_usage [] |
static struct ao2_container * | iax_peercallno_pvts |
Another container of iax2_pvt structures. | |
static int | iaxactivethreadcount = 0 |
static int | iaxcompat = 0 |
static int | iaxdebug = 0 |
static int | iaxdefaultdpcache = 10 * 60 |
static int | iaxdefaulttimeout = 5 |
static int | iaxdynamicthreadcount = 0 |
static int | iaxdynamicthreadnum = 0 |
static int | iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT |
ast_custom_function | iaxpeer_function |
static struct ast_iax2_queue | iaxq |
static struct chan_iax2_pvt * | iaxs [IAX_MAX_CALLS] |
static ast_mutex_t | iaxsl [ARRAY_LEN(iaxs)] |
static int | iaxthreadcount = DEFAULT_THREAD_COUNT |
static int | iaxtrunkdebug = 0 |
static struct io_context * | io |
static int | lagrq_time = 10 |
static char | language [MAX_LANGUAGE] = "" |
static int | last_authmethod = 0 |
static struct timeval | lastused [ARRAY_LEN(iaxs)] |
static int | max_reg_expire |
static int | max_retries = 4 |
static int | maxauthreq = 3 |
static int | maxjitterbuffer = 1000 |
static int | maxjitterinterps = 10 |
static int | maxnontrunkcall = 1 |
static int | maxtrunkcall = TRUNK_CALL_START |
static int | min_reg_expire |
static char | mohinterpret [MAX_MUSICCLASS] |
static char | mohsuggest [MAX_MUSICCLASS] |
static struct ast_netsock_list * | netsock |
static pthread_t | netthreadid = AST_PTHREADT_NULL |
static char | no_debug_jb_usage [] |
static char | no_debug_trunk_usage [] |
static char | no_debug_usage [] |
static struct ast_netsock_list * | outsock |
static char * | papp = "IAX2Provision" |
static char * | pdescrip |
static struct ao2_container * | peers |
static int | ping_time = 21 |
static struct ast_codec_pref | prefs |
static char | prune_realtime_usage [] |
static char * | psyn = "Provision a calling IAXy with a given template" |
static char | regcontext [AST_MAX_CONTEXT] = "" |
static int | resyncthreshold = 1000 |
static struct sched_context * | sched |
static ast_cond_t | sched_cond |
static ast_mutex_t | sched_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
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 ast_mutex_t | tpeerlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static struct iax2_trunk_peer * | tpeers |
static int | trunkfreq = 20 |
static struct ao2_container * | users |
static struct ast_firmware_list | waresl |
Definition in file chan_iax2.c.
#define CACHE_FLAG_CANEXIST (1 << 2) |
Extension can exist
Definition at line 664 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 660 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 674 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 662 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 666 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 668 of file chan_iax2.c.
Referenced by find_cache(), and iax2_show_cache().
#define CACHE_FLAG_TRANSMITTED (1 << 5) |
Request transmitted
Definition at line 670 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 672 of file chan_iax2.c.
Referenced by complete_dpreply(), and iax2_show_cache().
#define CALLNO_TO_PTR | ( | a | ) | ((void *)(unsigned long)(a)) |
Definition at line 123 of file chan_iax2.c.
Referenced by ast_iax2_new(), iax2_call(), iax2_hangup(), and update_jbsched().
#define DEBUG_SCHED_MULTITHREAD |
Definition at line 111 of file chan_iax2.c.
#define DEBUG_SUPPORT |
Definition at line 131 of file chan_iax2.c.
#define DEFAULT_DROP 3 |
Definition at line 129 of file chan_iax2.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 197 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 196 of file chan_iax2.c.
Referenced by build_peer(), and handle_response_peerpoke().
#define DEFAULT_MAX_THREAD_COUNT 100 |
Definition at line 126 of file chan_iax2.c.
#define DEFAULT_MAXMS 2000 |
Definition at line 195 of file chan_iax2.c.
#define DEFAULT_RETRY_TIME 1000 |
#define DEFAULT_THREAD_COUNT 10 |
Definition at line 125 of file chan_iax2.c.
#define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 440 of file chan_iax2.c.
Referenced by iax2_trunk_queue().
#define FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s\n" |
#define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
#define FORMAT "%-15.15s %-15d %-15d\n" |
#define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" |
#define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
#define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" |
#define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
#define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" |
#define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" |
#define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
#define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
#define GAMMA (0.01) |
Definition at line 136 of file chan_iax2.c.
#define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
#define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
Definition at line 178 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 186 of file chan_iax2.c.
Referenced by set_config().
#define IAX_CAPABILITY_LOWFREE |
Value:
Definition at line 191 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 180 of file chan_iax2.c.
Referenced by set_config().
#define IAX_IOSTATE_IDLE 0 |
#define IAX_IOSTATE_PROCESSING 2 |
Definition at line 697 of file chan_iax2.c.
#define IAX_IOSTATE_READY 1 |
#define IAX_IOSTATE_SCHEDREADY 3 |
#define IAX_TYPE_DYNAMIC 2 |
Definition at line 701 of file chan_iax2.c.
Referenced by find_idle_thread(), iax2_process_thread(), iax2_show_threads(), and insert_idle_thread().
#define IAX_TYPE_POOL 1 |
#define IPTOS_MINCOST 0x02 |
Definition at line 114 of file chan_iax2.c.
#define MAX_JITTER_BUFFER 50 |
Definition at line 437 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 646 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 443 of file chan_iax2.c.
#define MAX_TRUNKDATA 640 * 200 |
40ms, uncompressed linear * 200 channels
Definition at line 441 of file chan_iax2.c.
Referenced by iax2_trunk_queue(), and timing_read().
#define MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define MEMORY_SIZE 100 |
Definition at line 128 of file chan_iax2.c.
#define MIN_JITTER_BUFFER 10 |
Definition at line 438 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 1455 of file chan_iax2.c.
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_poke_peer(), iax2_provision(), and iax2_request().
#define NEW_PREVENT 0 |
#define PTR_TO_CALLNO | ( | a | ) | ((unsigned short)(unsigned long)(a)) |
Definition at line 122 of file chan_iax2.c.
Referenced by __auto_congest(), __get_from_jb(), function_iaxpeer(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_digit_begin(), iax2_digit_end(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_prov_app(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), iax2_transfer(), iax2_write(), and scheduled_destroy().
#define SCHED_MULTITHREADED |
Definition at line 107 of file chan_iax2.c.
#define schedule_action | ( | func, | |||
data | ) | __schedule_action(func, data, __PRETTY_FUNCTION__) |
Definition at line 982 of file chan_iax2.c.
Referenced by attempt_transmit(), auth_reject(), auto_congest(), auto_hangup(), expire_registry(), get_from_jb(), iax2_do_register_s(), iax2_poke_noanswer(), iax2_poke_peer_s(), send_lagrq(), and send_ping().
#define TRUNK_CALL_START ARRAY_LEN(iaxs) / 2 |
Definition at line 828 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 446 of file chan_iax2.c.
anonymous enum |
Definition at line 231 of file chan_iax2.c.
00231 { 00232 IAX_STATE_STARTED = (1 << 0), 00233 IAX_STATE_AUTHENTICATED = (1 << 1), 00234 IAX_STATE_TBD = (1 << 2), 00235 IAX_STATE_UNCHANGED = (1 << 3), 00236 } iax2_state;
anonymous enum |
Definition at line 243 of file chan_iax2.c.
00243 { 00244 IAX_HASCALLERID = (1 << 0), /*!< CallerID has been specified */ 00245 IAX_DELME = (1 << 1), /*!< Needs to be deleted */ 00246 IAX_TEMPONLY = (1 << 2), /*!< Temporary (realtime) */ 00247 IAX_TRUNK = (1 << 3), /*!< Treat as a trunk */ 00248 IAX_NOTRANSFER = (1 << 4), /*!< Don't native bridge */ 00249 IAX_USEJITTERBUF = (1 << 5), /*!< Use jitter buffer */ 00250 IAX_DYNAMIC = (1 << 6), /*!< dynamic peer */ 00251 IAX_SENDANI = (1 << 7), /*!< Send ANI along with CallerID */ 00252 /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */ 00253 IAX_ALREADYGONE = (1 << 9), /*!< Already disconnected */ 00254 IAX_PROVISION = (1 << 10), /*!< This is a provisioning request */ 00255 IAX_QUELCH = (1 << 11), /*!< Whether or not we quelch audio */ 00256 IAX_ENCRYPTED = (1 << 12), /*!< Whether we should assume encrypted tx/rx */ 00257 IAX_KEYPOPULATED = (1 << 13), /*!< Whether we have a key populated */ 00258 IAX_CODEC_USER_FIRST = (1 << 14), /*!< are we willing to let the other guy choose the codec? */ 00259 IAX_CODEC_NOPREFS = (1 << 15), /*!< Force old behaviour by turning off prefs */ 00260 IAX_CODEC_NOCAP = (1 << 16), /*!< only consider requested format and ignore capabilities*/ 00261 IAX_RTCACHEFRIENDS = (1 << 17), /*!< let realtime stay till your reload */ 00262 IAX_RTUPDATE = (1 << 18), /*!< Send a realtime update */ 00263 IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */ 00264 IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 00265 IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */ 00266 IAX_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */ 00267 IAX_TRANSFERMEDIA = (1 << 23), /*!< When doing IAX2 transfers, transfer media only */ 00268 IAX_MAXAUTHREQ = (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */ 00269 IAX_DELAYPBXSTART = (1 << 25), /*!< Don't start a PBX on the channel until the peer sends us a 00270 response, so that we've achieved a three-way handshake with 00271 them before sending voice or anything else*/ 00272 IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */ 00273 } 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 392 of file chan_iax2.c.
00392 { 00393 REG_STATE_UNREGISTERED = 0, 00394 REG_STATE_REGSENT, 00395 REG_STATE_AUTHSENT, 00396 REG_STATE_REGISTERED, 00397 REG_STATE_REJECTED, 00398 REG_STATE_TIMEOUT, 00399 REG_STATE_NOAUTH 00400 };
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 402 of file chan_iax2.c.
00402 { 00403 TRANSFER_NONE = 0, 00404 TRANSFER_BEGIN, 00405 TRANSFER_READY, 00406 TRANSFER_RELEASED, 00407 TRANSFER_PASSTHROUGH, 00408 TRANSFER_MBEGIN, 00409 TRANSFER_MREADY, 00410 TRANSFER_MRELEASED, 00411 TRANSFER_MPASSTHROUGH, 00412 TRANSFER_MEDIA, 00413 TRANSFER_MEDIAPASS 00414 };
static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 2213 of file chan_iax2.c.
References AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), attempt_transmit(), iax2_registry::callno, ast_iax2_queue::count, chan_iax2_pvt::error, f, ast_frame::frametype, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), iax2_sched_add(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxq, iaxs, iaxsl, LOG_WARNING, MAX_RETRY_TIME, ast_format::name, chan_iax2_pvt::owner, ast_iax2_queue::queue, 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().
02214 { 02215 /* Attempt to transmit the frame to the remote peer... 02216 Called without iaxsl held. */ 02217 struct iax_frame *f = (struct iax_frame *)data; 02218 int freeme=0; 02219 int callno = f->callno; 02220 /* Make sure this call is still active */ 02221 if (callno) 02222 ast_mutex_lock(&iaxsl[callno]); 02223 if (callno && iaxs[callno]) { 02224 if ((f->retries < 0) /* Already ACK'd */ || 02225 (f->retries >= max_retries) /* Too many attempts */) { 02226 /* Record an error if we've transmitted too many times */ 02227 if (f->retries >= max_retries) { 02228 if (f->transfer) { 02229 /* Transfer timeout */ 02230 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 02231 } else if (f->final) { 02232 if (f->final) 02233 iax2_destroy(callno); 02234 } else { 02235 if (iaxs[callno]->owner) 02236 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); 02237 iaxs[callno]->error = ETIMEDOUT; 02238 if (iaxs[callno]->owner) { 02239 struct ast_frame fr = { 0, }; 02240 /* Hangup the fd */ 02241 fr.frametype = AST_FRAME_CONTROL; 02242 fr.subclass = AST_CONTROL_HANGUP; 02243 iax2_queue_frame(callno, &fr); // XXX 02244 /* Remember, owner could disappear */ 02245 if (iaxs[callno] && iaxs[callno]->owner) 02246 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 02247 } else { 02248 if (iaxs[callno]->reg) { 02249 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 02250 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 02251 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 02252 } 02253 iax2_destroy(callno); 02254 } 02255 } 02256 02257 } 02258 freeme++; 02259 } else { 02260 /* Update it if it needs it */ 02261 update_packet(f); 02262 /* Attempt transmission */ 02263 send_packet(f); 02264 f->retries++; 02265 /* Try again later after 10 times as long */ 02266 f->retrytime *= 10; 02267 if (f->retrytime > MAX_RETRY_TIME) 02268 f->retrytime = MAX_RETRY_TIME; 02269 /* Transfer messages max out at one second */ 02270 if (f->transfer && (f->retrytime > 1000)) 02271 f->retrytime = 1000; 02272 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 02273 } 02274 } else { 02275 /* Make sure it gets freed */ 02276 f->retries = -1; 02277 freeme++; 02278 } 02279 if (callno) 02280 ast_mutex_unlock(&iaxsl[callno]); 02281 /* Do not try again */ 02282 if (freeme) { 02283 /* Don't attempt delivery, just remove it from the queue */ 02284 AST_LIST_LOCK(&iaxq.queue); 02285 AST_LIST_REMOVE(&iaxq.queue, f, list); 02286 iaxq.count--; 02287 AST_LIST_UNLOCK(&iaxq.queue); 02288 f->retrans = -1; 02289 /* Free the IAX frame */ 02290 iax2_frame_free(f); 02291 } 02292 }
static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 6476 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().
06477 { 06478 /* Called from IAX thread only, without iaxs lock */ 06479 int callno = (int)(long)(nothing); 06480 struct iax_ie_data ied; 06481 ast_mutex_lock(&iaxsl[callno]); 06482 if (iaxs[callno]) { 06483 memset(&ied, 0, sizeof(ied)); 06484 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 06485 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 06486 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 06487 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 06488 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 06489 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 06490 } 06491 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 06492 } 06493 ast_mutex_unlock(&iaxsl[callno]); 06494 }
static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 3174 of file chan_iax2.c.
References AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), f, iax2_queue_frame(), iaxs, iaxsl, chan_iax2_pvt::initid, LOG_NOTICE, and PTR_TO_CALLNO.
Referenced by auto_congest().
03175 { 03176 int callno = PTR_TO_CALLNO(nothing); 03177 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 03178 ast_mutex_lock(&iaxsl[callno]); 03179 if (iaxs[callno]) { 03180 iaxs[callno]->initid = -1; 03181 iax2_queue_frame(callno, &f); 03182 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 03183 } 03184 ast_mutex_unlock(&iaxsl[callno]); 03185 }
static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 6525 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().
06526 { 06527 /* Called from IAX thread only, without iaxs lock */ 06528 int callno = (int)(long)(nothing); 06529 struct iax_ie_data ied; 06530 ast_mutex_lock(&iaxsl[callno]); 06531 if (iaxs[callno]) { 06532 memset(&ied, 0, sizeof(ied)); 06533 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 06534 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 06535 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 06536 } 06537 ast_mutex_unlock(&iaxsl[callno]); 06538 }
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 2080 of file chan_iax2.c.
References iax_frame::af, ast_clear_flag, AST_FRFLAG_HAS_TIMING_INFO, ast_test_flag, iax_frame::callno, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, and iax_frame::retrans.
Referenced by __get_from_jb(), and schedule_delivery().
02081 { 02082 /* Just deliver the packet by using queueing. This is called by 02083 the IAX thread with the iaxsl lock held. */ 02084 struct iax_frame *fr = data; 02085 fr->retrans = -1; 02086 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 02087 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 02088 iax2_queue_frame(fr->callno, &fr->af); 02089 /* Free our iax frame */ 02090 iax2_frame_free(fr); 02091 /* And don't run again */ 02092 return 0; 02093 }
static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 6158 of file chan_iax2.c.
References iax2_peer::addr, ast_db_del(), ast_device_state_changed(), ast_log(), ast_test_flag, EVENT_FLAG_SYSTEM, iax2_peer::expire, iax2_peer::expiry, globalflags, iax2_regfunk, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_TEMPONLY, manager_event(), iax2_peer::name, option_debug, peer_unref(), realtime_update_peer(), register_peer_exten(), and unlink_peer().
Referenced by expire_registry().
06159 { 06160 struct iax2_peer *peer = (struct iax2_peer *) data; 06161 06162 if (!peer) 06163 return; 06164 06165 peer->expire = -1; 06166 06167 if (option_debug) 06168 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name); 06169 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 06170 realtime_update_peer(peer->name, &peer->addr, 0); 06171 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 06172 /* Reset the address */ 06173 memset(&peer->addr, 0, sizeof(peer->addr)); 06174 /* Reset expiry value */ 06175 peer->expiry = min_reg_expire; 06176 if (!ast_test_flag(peer, IAX_TEMPONLY)) 06177 ast_db_del("IAX/Registry", peer->name); 06178 register_peer_exten(peer, 0); 06179 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 06180 if (iax2_regfunk) 06181 iax2_regfunk(peer->name, 0); 06182 06183 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) 06184 unlink_peer(peer); 06185 06186 peer_unref(peer); 06187 }
static int __find_callno | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | sockfd, | |||
int | return_locked, | |||
int | check_dcallno | |||
) | [static] |
Definition at line 1544 of file chan_iax2.c.
References chan_iax2_pvt::addr, ao2_find(), ao2_ref(), ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_string_field_set, ast_tvnow(), chan_iax2_pvt::callno, DEFAULT_RETRY_TIME, globalflags, iax2_getpeername(), iax2_sched_add(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, iax_peercallno_pvts, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, LOG_DEBUG, LOG_WARNING, match(), MIN_REUSE_TIME, NEW_ALLOW, new_iax(), option_debug, chan_iax2_pvt::peercallno, sched, send_lagrq(), send_ping(), store_by_peercallno(), TRUNK_CALL_START, and update_max_nontrunk().
Referenced by find_callno(), and find_callno_locked().
01545 { 01546 int res = 0; 01547 int x; 01548 struct timeval now; 01549 char host[80]; 01550 01551 if (new <= NEW_ALLOW) { 01552 if (callno) { 01553 struct chan_iax2_pvt *pvt; 01554 struct chan_iax2_pvt tmp_pvt = { 01555 .callno = dcallno, 01556 .peercallno = callno, 01557 /* hack!! */ 01558 .frames_received = check_dcallno, 01559 }; 01560 01561 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 01562 01563 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 01564 if (return_locked) { 01565 ast_mutex_lock(&iaxsl[pvt->callno]); 01566 } 01567 res = pvt->callno; 01568 ao2_ref(pvt, -1); 01569 pvt = NULL; 01570 return res; 01571 } 01572 } 01573 01574 /* This will occur on the first response to a message that we initiated, 01575 * such as a PING. */ 01576 if (dcallno) { 01577 ast_mutex_lock(&iaxsl[dcallno]); 01578 } 01579 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) { 01580 iaxs[dcallno]->peercallno = callno; 01581 res = dcallno; 01582 store_by_peercallno(iaxs[dcallno]); 01583 if (!res || !return_locked) { 01584 ast_mutex_unlock(&iaxsl[dcallno]); 01585 } 01586 return res; 01587 } 01588 if (dcallno) { 01589 ast_mutex_unlock(&iaxsl[dcallno]); 01590 } 01591 01592 #ifdef IAX_OLD_FIND 01593 /* If we get here, we SHOULD NOT find a call structure for this 01594 callno; if we do, it means that there is a call structure that 01595 has a peer callno but did NOT get entered into the hash table, 01596 which is bad. 01597 01598 If we find a call structure using this old, slow method, output a log 01599 message so we'll know about it. After a few months of leaving this in 01600 place, if we don't hear about people seeing these messages, we can 01601 remove this code for good. 01602 */ 01603 01604 for (x = 1; !res && x < maxnontrunkcall; x++) { 01605 ast_mutex_lock(&iaxsl[x]); 01606 if (iaxs[x]) { 01607 /* Look for an exact match */ 01608 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 01609 res = x; 01610 } 01611 } 01612 if (!res || !return_locked) 01613 ast_mutex_unlock(&iaxsl[x]); 01614 } 01615 01616 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 01617 ast_mutex_lock(&iaxsl[x]); 01618 if (iaxs[x]) { 01619 /* Look for an exact match */ 01620 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 01621 res = x; 01622 } 01623 } 01624 if (!res || !return_locked) 01625 ast_mutex_unlock(&iaxsl[x]); 01626 } 01627 01628 if (res) { 01629 ast_log(LOG_WARNING, "Old call search code found call number %d that was not in hash table!\n", res); 01630 } 01631 #endif 01632 } 01633 if (!res && (new >= NEW_ALLOW)) { 01634 int start, found = 0; 01635 01636 /* It may seem odd that we look through the peer list for a name for 01637 * this *incoming* call. Well, it is weird. However, users don't 01638 * have an IP address/port number that we can match against. So, 01639 * this is just checking for a peer that has that IP/port and 01640 * assuming that we have a user of the same name. This isn't always 01641 * correct, but it will be changed if needed after authentication. */ 01642 if (!iax2_getpeername(*sin, host, sizeof(host))) 01643 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 01644 01645 now = ast_tvnow(); 01646 start = 2 + (ast_random() % (TRUNK_CALL_START - 1)); 01647 for (x = start; 1; x++) { 01648 if (x == TRUNK_CALL_START) { 01649 x = 1; 01650 continue; 01651 } 01652 01653 /* Find first unused call number that hasn't been used in a while */ 01654 ast_mutex_lock(&iaxsl[x]); 01655 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01656 found = 1; 01657 break; 01658 } 01659 ast_mutex_unlock(&iaxsl[x]); 01660 01661 if (x == start - 1) { 01662 break; 01663 } 01664 } 01665 /* We've still got lock held if we found a spot */ 01666 if (x == start - 1 && !found) { 01667 ast_log(LOG_WARNING, "No more space\n"); 01668 return 0; 01669 } 01670 iaxs[x] = new_iax(sin, host); 01671 update_max_nontrunk(); 01672 if (iaxs[x]) { 01673 if (option_debug && iaxdebug) 01674 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x); 01675 iaxs[x]->sockfd = sockfd; 01676 iaxs[x]->addr.sin_port = sin->sin_port; 01677 iaxs[x]->addr.sin_family = sin->sin_family; 01678 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 01679 iaxs[x]->peercallno = callno; 01680 iaxs[x]->callno = x; 01681 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 01682 iaxs[x]->expiry = min_reg_expire; 01683 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01684 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01685 iaxs[x]->amaflags = amaflags; 01686 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 01687 01688 ast_string_field_set(iaxs[x], accountcode, accountcode); 01689 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 01690 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 01691 01692 if (iaxs[x]->peercallno) { 01693 store_by_peercallno(iaxs[x]); 01694 } 01695 } else { 01696 ast_log(LOG_WARNING, "Out of resources\n"); 01697 ast_mutex_unlock(&iaxsl[x]); 01698 return 0; 01699 } 01700 if (!return_locked) 01701 ast_mutex_unlock(&iaxsl[x]); 01702 res = x; 01703 } 01704 return res; 01705 }
static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 2616 of file chan_iax2.c.
References __do_deliver(), ast_codec_interp_len(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_mutex_lock(), ast_mutex_unlock(), ast_samp2tv(), ast_test_flag, ast_tvadd(), ast_tvdiff_ms(), iax2_registry::callno, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, iaxsl, chan_iax2_pvt::jb, JB_DROP, JB_EMPTY, jb_get(), JB_INTERP, jb_next(), JB_NOFRAME, JB_OK, chan_iax2_pvt::jbid, jb_frame::ms, iax2_registry::next, 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().
02617 { 02618 int callno = PTR_TO_CALLNO(p); 02619 struct chan_iax2_pvt *pvt = NULL; 02620 struct iax_frame *fr; 02621 jb_frame frame; 02622 int ret; 02623 long now; 02624 long next; 02625 struct timeval tv; 02626 02627 /* Make sure we have a valid private structure before going on */ 02628 ast_mutex_lock(&iaxsl[callno]); 02629 pvt = iaxs[callno]; 02630 if (!pvt) { 02631 /* No go! */ 02632 ast_mutex_unlock(&iaxsl[callno]); 02633 return; 02634 } 02635 02636 pvt->jbid = -1; 02637 02638 gettimeofday(&tv,NULL); 02639 /* round up a millisecond since ast_sched_runq does; */ 02640 /* prevents us from spinning while waiting for our now */ 02641 /* to catch up with runq's now */ 02642 tv.tv_usec += 1000; 02643 02644 now = ast_tvdiff_ms(tv, pvt->rxcore); 02645 02646 if(now >= (next = jb_next(pvt->jb))) { 02647 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat)); 02648 switch(ret) { 02649 case JB_OK: 02650 fr = frame.data; 02651 __do_deliver(fr); 02652 /* __do_deliver() can cause the call to disappear */ 02653 pvt = iaxs[callno]; 02654 break; 02655 case JB_INTERP: 02656 { 02657 struct ast_frame af = { 0, }; 02658 02659 /* create an interpolation frame */ 02660 af.frametype = AST_FRAME_VOICE; 02661 af.subclass = pvt->voiceformat; 02662 af.samples = frame.ms * 8; 02663 af.src = "IAX2 JB interpolation"; 02664 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 02665 af.offset = AST_FRIENDLY_OFFSET; 02666 02667 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 02668 * which we'd need to malloc, and then it would free it. That seems like a drag */ 02669 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) { 02670 iax2_queue_frame(callno, &af); 02671 /* iax2_queue_frame() could cause the call to disappear */ 02672 pvt = iaxs[callno]; 02673 } 02674 } 02675 break; 02676 case JB_DROP: 02677 iax2_frame_free(frame.data); 02678 break; 02679 case JB_NOFRAME: 02680 case JB_EMPTY: 02681 /* do nothing */ 02682 break; 02683 default: 02684 /* shouldn't happen */ 02685 break; 02686 } 02687 } 02688 if (pvt) 02689 update_jbsched(pvt); 02690 ast_mutex_unlock(&iaxsl[callno]); 02691 }
static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 5847 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
05848 { 05849 struct iax2_registry *reg = (struct iax2_registry *)data; 05850 reg->expire = -1; 05851 iax2_do_register(reg); 05852 }
static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 8969 of file chan_iax2.c.
References ast_device_state_changed(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_peer::callno, EVENT_FLAG_SYSTEM, iax2_destroy(), iax2_poke_peer_s(), iax2_sched_add(), iaxsl, iax2_peer::lastms, LOG_NOTICE, manager_event(), iax2_peer::name, peer_ref(), peer_unref(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, and sched.
Referenced by iax2_poke_noanswer().
08970 { 08971 struct iax2_peer *peer = (struct iax2_peer *)data; 08972 int callno; 08973 08974 if (peer->lastms > -1) { 08975 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 08976 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 08977 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 08978 } 08979 if ((callno = peer->callno) > 0) { 08980 ast_mutex_lock(&iaxsl[callno]); 08981 iax2_destroy(callno); 08982 ast_mutex_unlock(&iaxsl[callno]); 08983 } 08984 peer->callno = 0; 08985 peer->lastms = -1; 08986 /* Try again quickly */ 08987 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 08988 if (peer->pokeexpire == -1) 08989 peer_unref(peer); 08990 }
static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 6588 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
06589 { 06590 struct iax2_peer *peer = (struct iax2_peer *)data; 06591 iax2_poke_peer(peer, 0); 06592 peer_unref(peer); 06593 }
static int __iax2_show_peers | ( | int | manager, | |
int | fd, | |||
struct mansession * | s, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4634 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), ast_cli(), ast_copy_string(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_append(), iax2_peer::encmethods, FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, iax2_peer::name, name, peer_status(), peer_unref(), RESULT_SHOWUSAGE, RESULT_SUCCESS, s, and iax2_peer::username.
Referenced by iax2_show_peers(), and manager_iax2_show_peers().
04635 { 04636 regex_t regexbuf; 04637 int havepattern = 0; 04638 int total_peers = 0; 04639 int online_peers = 0; 04640 int offline_peers = 0; 04641 int unmonitored_peers = 0; 04642 struct ao2_iterator i; 04643 04644 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 04645 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 04646 04647 struct iax2_peer *peer = NULL; 04648 char name[256]; 04649 int registeredonly=0; 04650 char *term = manager ? "\r\n" : "\n"; 04651 04652 switch (argc) { 04653 case 6: 04654 if (!strcasecmp(argv[3], "registered")) 04655 registeredonly = 1; 04656 else 04657 return RESULT_SHOWUSAGE; 04658 if (!strcasecmp(argv[4], "like")) { 04659 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 04660 return RESULT_SHOWUSAGE; 04661 havepattern = 1; 04662 } else 04663 return RESULT_SHOWUSAGE; 04664 break; 04665 case 5: 04666 if (!strcasecmp(argv[3], "like")) { 04667 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04668 return RESULT_SHOWUSAGE; 04669 havepattern = 1; 04670 } else 04671 return RESULT_SHOWUSAGE; 04672 break; 04673 case 4: 04674 if (!strcasecmp(argv[3], "registered")) 04675 registeredonly = 1; 04676 else 04677 return RESULT_SHOWUSAGE; 04678 break; 04679 case 3: 04680 break; 04681 default: 04682 return RESULT_SHOWUSAGE; 04683 } 04684 04685 04686 if (s) 04687 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04688 else 04689 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04690 04691 i = ao2_iterator_init(peers, 0); 04692 for (peer = ao2_iterator_next(&i); peer; 04693 peer_unref(peer), peer = ao2_iterator_next(&i)) { 04694 char nm[20]; 04695 char status[20]; 04696 char srch[2000]; 04697 int retstatus; 04698 04699 if (registeredonly && !peer->addr.sin_addr.s_addr) 04700 continue; 04701 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 04702 continue; 04703 04704 if (!ast_strlen_zero(peer->username)) 04705 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 04706 else 04707 ast_copy_string(name, peer->name, sizeof(name)); 04708 04709 retstatus = peer_status(peer, status, sizeof(status)); 04710 if (retstatus > 0) 04711 online_peers++; 04712 else if (!retstatus) 04713 offline_peers++; 04714 else 04715 unmonitored_peers++; 04716 04717 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 04718 04719 snprintf(srch, sizeof(srch), FORMAT, name, 04720 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04721 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04722 nm, 04723 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04724 peer->encmethods ? "(E)" : " ", status, term); 04725 04726 if (s) 04727 astman_append(s, FORMAT, name, 04728 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)", 04729 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04730 nm, 04731 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04732 peer->encmethods ? "(E)" : " ", status, term); 04733 else 04734 ast_cli(fd, FORMAT, name, 04735 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04736 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04737 nm, 04738 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04739 peer->encmethods ? "(E)" : " ", status, term); 04740 total_peers++; 04741 } 04742 04743 if (s) 04744 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04745 else 04746 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04747 04748 if (havepattern) 04749 regfree(®exbuf); 04750 04751 return RESULT_SUCCESS; 04752 #undef FORMAT 04753 #undef FORMAT2 04754 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 11337 of file chan_iax2.c.
static int __schedule_action | ( | void(*)(const void *data) | func, | |
const void * | data, | |||
const char * | funcname | |||
) | [static] |
Definition at line 957 of file chan_iax2.c.
References ast_copy_string(), ast_log(), find_idle_thread(), IAX_IOSTATE_SCHEDREADY, LOG_DEBUG, option_debug, signal_condition(), t, and thread.
00958 { 00959 struct iax2_thread *thread = NULL; 00960 static time_t lasterror; 00961 static time_t t; 00962 00963 thread = find_idle_thread(); 00964 00965 if (thread != NULL) { 00966 thread->schedfunc = func; 00967 thread->scheddata = data; 00968 thread->iostate = IAX_IOSTATE_SCHEDREADY; 00969 #ifdef DEBUG_SCHED_MULTITHREAD 00970 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 00971 #endif 00972 signal_condition(&thread->lock, &thread->cond); 00973 return 0; 00974 } 00975 time(&t); 00976 if (t != lasterror && option_debug) 00977 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n"); 00978 lasterror = t; 00979 00980 return -1; 00981 }
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 5135 of file chan_iax2.c.
References f, and iax2_send().
Referenced by send_command(), send_command_final(), send_command_immediate(), and send_command_transfer().
05137 { 05138 struct ast_frame f = { 0, }; 05139 05140 f.frametype = type; 05141 f.subclass = command; 05142 f.datalen = datalen; 05143 f.src = __FUNCTION__; 05144 f.data = (void *) data; 05145 05146 return iax2_send(i, &f, ts, seqno, now, transfer, final); 05147 }
static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1042 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_sched_add(), IAX_COMMAND_LAGRQ, LOG_WARNING, sched, send_command(), and send_lagrq().
Referenced by send_lagrq().
01043 { 01044 int callno = (long) data; 01045 01046 ast_mutex_lock(&iaxsl[callno]); 01047 01048 if (iaxs[callno]) { 01049 if (iaxs[callno]->peercallno) { 01050 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01051 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01052 } else { 01053 /* I am the schedule, so I'm allowed to do this */ 01054 iaxs[callno]->lagid = -1; 01055 } 01056 } else { 01057 ast_log(LOG_WARNING, "I was supposed to send a LAGRQ with callno %d, but no such call exists (and I cannot remove lagid, either).\n", callno); 01058 } 01059 01060 ast_mutex_unlock(&iaxsl[callno]); 01061 }
static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 997 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_sched_add(), IAX_COMMAND_PING, LOG_DEBUG, option_debug, sched, send_command(), and send_ping().
Referenced by send_ping().
00998 { 00999 int callno = (long) data; 01000 01001 ast_mutex_lock(&iaxsl[callno]); 01002 01003 if (iaxs[callno]) { 01004 if (iaxs[callno]->peercallno) { 01005 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01006 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01007 } else { 01008 /* I am the schedule, so I'm allowed to do this */ 01009 iaxs[callno]->pingid = -1; 01010 } 01011 } else if (option_debug > 0) { 01012 ast_log(LOG_DEBUG, "I was supposed to send a PING with callno %d, but no such call exists (and I cannot remove pingid, either).\n", callno); 01013 } 01014 01015 ast_mutex_unlock(&iaxsl[callno]); 01016 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 11096 of file chan_iax2.c.
References ao2_ref(), ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_cond_signal(), AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_manager_unregister(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_netsock_release(), AST_PTHREADT_NULL, ast_unregister_application(), ast_unregister_switch(), cli_iax2, delete_users(), iax2_destroy(), iax2_switch, iax2_tech, iax_peercallno_pvts, iax_provision_unload(), iaxactivethreadcount, iaxq, iaxs, iaxsl, iax2_thread::list, ast_firmware_list::lock, netsock, outsock, ast_iax2_queue::queue, reload_firmware(), sched, sched_context_destroy(), sched_lock, thread, and waresl.
11097 { 11098 struct iax2_thread *thread = NULL; 11099 int x; 11100 11101 /* Make sure threads do not hold shared resources when they are canceled */ 11102 11103 /* Grab the sched lock resource to keep it away from threads about to die */ 11104 /* Cancel the network thread, close the net socket */ 11105 if (netthreadid != AST_PTHREADT_NULL) { 11106 AST_LIST_LOCK(&iaxq.queue); 11107 ast_mutex_lock(&sched_lock); 11108 pthread_cancel(netthreadid); 11109 ast_cond_signal(&sched_cond); 11110 ast_mutex_unlock(&sched_lock); /* Release the schedule lock resource */ 11111 AST_LIST_UNLOCK(&iaxq.queue); 11112 pthread_join(netthreadid, NULL); 11113 } 11114 if (schedthreadid != AST_PTHREADT_NULL) { 11115 ast_mutex_lock(&sched_lock); 11116 pthread_cancel(schedthreadid); 11117 ast_cond_signal(&sched_cond); 11118 ast_mutex_unlock(&sched_lock); 11119 pthread_join(schedthreadid, NULL); 11120 } 11121 11122 /* Call for all threads to halt */ 11123 AST_LIST_LOCK(&idle_list); 11124 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) { 11125 AST_LIST_REMOVE_CURRENT(&idle_list, list); 11126 pthread_cancel(thread->threadid); 11127 } 11128 AST_LIST_TRAVERSE_SAFE_END 11129 AST_LIST_UNLOCK(&idle_list); 11130 11131 AST_LIST_LOCK(&active_list); 11132 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) { 11133 AST_LIST_REMOVE_CURRENT(&active_list, list); 11134 pthread_cancel(thread->threadid); 11135 } 11136 AST_LIST_TRAVERSE_SAFE_END 11137 AST_LIST_UNLOCK(&active_list); 11138 11139 AST_LIST_LOCK(&dynamic_list); 11140 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) { 11141 AST_LIST_REMOVE_CURRENT(&dynamic_list, list); 11142 pthread_cancel(thread->threadid); 11143 } 11144 AST_LIST_TRAVERSE_SAFE_END 11145 AST_LIST_UNLOCK(&dynamic_list); 11146 11147 AST_LIST_HEAD_DESTROY(&iaxq.queue); 11148 11149 /* Wait for threads to exit */ 11150 while(0 < iaxactivethreadcount) 11151 usleep(10000); 11152 11153 ast_netsock_release(netsock); 11154 ast_netsock_release(outsock); 11155 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 11156 if (iaxs[x]) { 11157 iax2_destroy(x); 11158 } 11159 } 11160 ast_manager_unregister( "IAXpeers" ); 11161 ast_manager_unregister( "IAXnetstats" ); 11162 ast_unregister_application(papp); 11163 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 11164 ast_unregister_switch(&iax2_switch); 11165 ast_channel_unregister(&iax2_tech); 11166 delete_users(); 11167 iax_provision_unload(); 11168 sched_context_destroy(sched); 11169 reload_firmware(1); 11170 11171 ast_mutex_destroy(&waresl.lock); 11172 11173 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 11174 ast_mutex_destroy(&iaxsl[x]); 11175 } 11176 11177 ao2_ref(peers, -1); 11178 ao2_ref(users, -1); 11179 ao2_ref(iax_peercallno_pvts, -1); 11180 11181 return 0; 11182 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 11337 of file chan_iax2.c.
static int apply_context | ( | struct iax2_context * | con, | |
const char * | context | |||
) | [static] |
Definition at line 5188 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
05189 { 05190 while(con) { 05191 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 05192 return -1; 05193 con = con->next; 05194 } 05195 return 0; 05196 }
static int ast_cli_netstats | ( | struct mansession * | s, | |
int | fd, | |||
int | limit_fmt | |||
) | [static] |
Definition at line 4962 of file chan_iax2.c.
References ARRAY_LEN, ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, astman_append(), jb_info::current, iax_rr::delay, iax_rr::dropped, jb_info::frames_dropped, jb_info::frames_lost, jb_info::frames_ooo, chan_iax2_pvt::frames_received, IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), iax_rr::jitter, jb_info::jitter, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, jb_info::min, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::pingtime, chan_iax2_pvt::remote_rr, and s.
Referenced by iax2_show_netstats(), and manager_iax2_show_netstats().
04963 { 04964 int x; 04965 int numchans = 0; 04966 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 04967 ast_mutex_lock(&iaxsl[x]); 04968 if (iaxs[x]) { 04969 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 04970 char *fmt; 04971 jb_info jbinfo; 04972 04973 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04974 jb_getinfo(iaxs[x]->jb, &jbinfo); 04975 localjitter = jbinfo.jitter; 04976 localdelay = jbinfo.current - jbinfo.min; 04977 locallost = jbinfo.frames_lost; 04978 locallosspct = jbinfo.losspct/1000; 04979 localdropped = jbinfo.frames_dropped; 04980 localooo = jbinfo.frames_ooo; 04981 } else { 04982 localjitter = -1; 04983 localdelay = 0; 04984 locallost = -1; 04985 locallosspct = -1; 04986 localdropped = 0; 04987 localooo = -1; 04988 } 04989 if (limit_fmt) 04990 fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n"; 04991 else 04992 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"; 04993 if (s) 04994 04995 astman_append(s, fmt, 04996 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04997 iaxs[x]->pingtime, 04998 localjitter, 04999 localdelay, 05000 locallost, 05001 locallosspct, 05002 localdropped, 05003 localooo, 05004 iaxs[x]->frames_received/1000, 05005 iaxs[x]->remote_rr.jitter, 05006 iaxs[x]->remote_rr.delay, 05007 iaxs[x]->remote_rr.losscnt, 05008 iaxs[x]->remote_rr.losspct, 05009 iaxs[x]->remote_rr.dropped, 05010 iaxs[x]->remote_rr.ooo, 05011 iaxs[x]->remote_rr.packets/1000); 05012 else 05013 ast_cli(fd, fmt, 05014 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 05015 iaxs[x]->pingtime, 05016 localjitter, 05017 localdelay, 05018 locallost, 05019 locallosspct, 05020 localdropped, 05021 localooo, 05022 iaxs[x]->frames_received/1000, 05023 iaxs[x]->remote_rr.jitter, 05024 iaxs[x]->remote_rr.delay, 05025 iaxs[x]->remote_rr.losscnt, 05026 iaxs[x]->remote_rr.losspct, 05027 iaxs[x]->remote_rr.dropped, 05028 iaxs[x]->remote_rr.ooo, 05029 iaxs[x]->remote_rr.packets/1000 05030 ); 05031 numchans++; 05032 } 05033 ast_mutex_unlock(&iaxsl[x]); 05034 } 05035 return numchans; 05036 }
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 3838 of file chan_iax2.c.
References chan_iax2_pvt::accountcode, chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, chan_iax2_pvt::ani, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_channel_alloc(), ast_channel_free(), ast_copy_string(), 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, chan_iax2_pvt::cid_name, chan_iax2_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, chan_iax2_pvt::context, chan_iax2_pvt::dnid, ast_channel::exten, chan_iax2_pvt::exten, chan_iax2_pvt::host, iax2_tech, iaxs, iaxsl, chan_iax2_pvt::language, 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::rawreadformat, ast_channel::rawwriteformat, chan_iax2_pvt::rdnis, 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().
03839 { 03840 struct ast_channel *tmp; 03841 struct chan_iax2_pvt *i; 03842 struct ast_variable *v = NULL; 03843 03844 if (!(i = iaxs[callno])) { 03845 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 03846 return NULL; 03847 } 03848 03849 /* Don't hold call lock */ 03850 ast_mutex_unlock(&iaxsl[callno]); 03851 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); 03852 ast_mutex_lock(&iaxsl[callno]); 03853 if (i != iaxs[callno]) { 03854 if (tmp) { 03855 /* unlock and relock iaxsl[callno] to preserve locking order */ 03856 ast_mutex_unlock(&iaxsl[callno]); 03857 ast_channel_free(tmp); 03858 ast_mutex_lock(&iaxsl[callno]); 03859 } 03860 return NULL; 03861 } 03862 03863 if (!tmp) 03864 return NULL; 03865 tmp->tech = &iax2_tech; 03866 /* We can support any format by default, until we get restricted */ 03867 tmp->nativeformats = capability; 03868 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability); 03869 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability); 03870 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 03871 03872 /* Don't use ast_set_callerid() here because it will 03873 * generate a NewCallerID event before the NewChannel event */ 03874 if (!ast_strlen_zero(i->ani)) 03875 tmp->cid.cid_ani = ast_strdup(i->ani); 03876 else 03877 tmp->cid.cid_ani = ast_strdup(i->cid_num); 03878 tmp->cid.cid_dnid = ast_strdup(i->dnid); 03879 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 03880 tmp->cid.cid_pres = i->calling_pres; 03881 tmp->cid.cid_ton = i->calling_ton; 03882 tmp->cid.cid_tns = i->calling_tns; 03883 if (!ast_strlen_zero(i->language)) 03884 ast_string_field_set(tmp, language, i->language); 03885 if (!ast_strlen_zero(i->accountcode)) 03886 ast_string_field_set(tmp, accountcode, i->accountcode); 03887 if (i->amaflags) 03888 tmp->amaflags = i->amaflags; 03889 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 03890 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 03891 if (i->adsi) 03892 tmp->adsicpe = i->peeradsicpe; 03893 else 03894 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 03895 i->owner = tmp; 03896 i->capability = capability; 03897 03898 for (v = i->vars ; v ; v = v->next) 03899 pbx_builtin_setvar_helper(tmp, v->name, v->value); 03900 03901 if (state != AST_STATE_DOWN) { 03902 if (ast_pbx_start(tmp)) { 03903 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 03904 ast_hangup(tmp); 03905 i->owner = NULL; 03906 return NULL; 03907 } 03908 } 03909 03910 ast_module_ref(ast_module_info->self); 03911 03912 return tmp; 03913 }
static int attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 2294 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and network_thread().
02295 { 02296 #ifdef SCHED_MULTITHREADED 02297 if (schedule_action(__attempt_transmit, data)) 02298 #endif 02299 __attempt_transmit(data); 02300 return 0; 02301 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 6510 of file chan_iax2.c.
References AST_SCHED_DEL, auth_reject(), chan_iax2_pvt::authfail, chan_iax2_pvt::authid, iax2_sched_add(), iaxs, and sched.
Referenced by socket_process().
06511 { 06512 /* Schedule sending the authentication failure in one second, to prevent 06513 guessing */ 06514 if (iaxs[callno]) { 06515 iaxs[callno]->authfail = failcode; 06516 if (delayreject) { 06517 AST_SCHED_DEL(sched, iaxs[callno]->authid); 06518 iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno); 06519 } else 06520 auth_reject((void *)(long)callno); 06521 } 06522 return 0; 06523 }
static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 6496 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().
06497 { 06498 int callno = (int)(long)(data); 06499 ast_mutex_lock(&iaxsl[callno]); 06500 if (iaxs[callno]) 06501 iaxs[callno]->authid = -1; 06502 ast_mutex_unlock(&iaxsl[callno]); 06503 #ifdef SCHED_MULTITHREADED 06504 if (schedule_action(__auth_reject, data)) 06505 #endif 06506 __auth_reject(data); 06507 return 0; 06508 }
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 5716 of file chan_iax2.c.
References ast_inet_ntoa(), ast_key_get, AST_KEY_PRIVATE, ast_log(), ast_sign, ast_strlen_zero(), build_enc_keys(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, iax_ie_append_str(), IAX_IE_MD5_RESULT, IAX_IE_PASSWORD, IAX_IE_RSA_RESULT, LOG_NOTICE, md5(), MD5Final(), MD5Init(), and MD5Update().
05717 { 05718 int res = -1; 05719 int x; 05720 if (!ast_strlen_zero(keyn)) { 05721 if (!(authmethods & IAX_AUTH_RSA)) { 05722 if (ast_strlen_zero(secret)) 05723 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)); 05724 } else if (ast_strlen_zero(challenge)) { 05725 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 05726 } else { 05727 char sig[256]; 05728 struct ast_key *key; 05729 key = ast_key_get(keyn, AST_KEY_PRIVATE); 05730 if (!key) { 05731 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 05732 } else { 05733 if (ast_sign(key, (char*)challenge, sig)) { 05734 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 05735 res = -1; 05736 } else { 05737 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 05738 res = 0; 05739 } 05740 } 05741 } 05742 } 05743 /* Fall back */ 05744 if (res && !ast_strlen_zero(secret)) { 05745 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 05746 struct MD5Context md5; 05747 unsigned char digest[16]; 05748 char digres[128]; 05749 MD5Init(&md5); 05750 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 05751 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 05752 MD5Final(digest, &md5); 05753 /* If they support md5, authenticate with it. */ 05754 for (x=0;x<16;x++) 05755 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 05756 if (ecx && dcx) 05757 build_enc_keys(digest, ecx, dcx); 05758 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 05759 res = 0; 05760 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 05761 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 05762 res = 0; 05763 } else 05764 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 05765 } 05766 return res; 05767 }
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 5773 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(), iax2_peer::name, iax2_peer::outkey, peer_unref(), realtime_peer(), iax2_peer::secret, send_command(), and iax2_peer::username.
Referenced by socket_process().
05774 { 05775 struct iax2_peer *peer = NULL; 05776 /* Start pessimistic */ 05777 int res = -1; 05778 int authmethods = 0; 05779 struct iax_ie_data ied; 05780 uint16_t callno = p->callno; 05781 05782 memset(&ied, 0, sizeof(ied)); 05783 05784 if (ies->username) 05785 ast_string_field_set(p, username, ies->username); 05786 if (ies->challenge) 05787 ast_string_field_set(p, challenge, ies->challenge); 05788 if (ies->authmethods) 05789 authmethods = ies->authmethods; 05790 if (authmethods & IAX_AUTH_MD5) 05791 merge_encryption(p, ies->encmethods); 05792 else 05793 p->encmethods = 0; 05794 05795 /* Check for override RSA authentication first */ 05796 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 05797 /* Normal password authentication */ 05798 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05799 } else { 05800 struct ao2_iterator i = ao2_iterator_init(peers, 0); 05801 while ((peer = ao2_iterator_next(&i))) { 05802 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 05803 /* No peer specified at our end, or this is the peer */ 05804 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 05805 /* No username specified in peer rule, or this is the right username */ 05806 && (!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))) 05807 /* No specified host, or this is our host */ 05808 ) { 05809 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05810 if (!res) { 05811 peer_unref(peer); 05812 break; 05813 } 05814 } 05815 peer_unref(peer); 05816 } 05817 if (!peer) { 05818 /* We checked our list and didn't find one. It's unlikely, but possible, 05819 that we're trying to authenticate *to* a realtime peer */ 05820 const char *peer_name = ast_strdupa(p->peer); 05821 ast_mutex_unlock(&iaxsl[callno]); 05822 if ((peer = realtime_peer(peer_name, NULL))) { 05823 ast_mutex_lock(&iaxsl[callno]); 05824 if (!(p = iaxs[callno])) { 05825 peer_unref(peer); 05826 return -1; 05827 } 05828 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05829 peer_unref(peer); 05830 } 05831 if (!peer) { 05832 ast_mutex_lock(&iaxsl[callno]); 05833 if (!(p = iaxs[callno])) 05834 return -1; 05835 } 05836 } 05837 } 05838 if (ies->encmethods) 05839 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 05840 if (!res) 05841 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 05842 return res; 05843 }
static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 5445 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, chan_iax2_pvt::challenge, 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 chan_iax2_pvt::username.
Referenced by socket_process().
05446 { 05447 struct iax_ie_data ied; 05448 int res = -1, authreq_restrict = 0; 05449 char challenge[10]; 05450 struct chan_iax2_pvt *p = iaxs[call_num]; 05451 05452 memset(&ied, 0, sizeof(ied)); 05453 05454 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 05455 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05456 struct iax2_user *user, tmp_user = { 05457 .name = p->username, 05458 }; 05459 05460 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05461 if (user) { 05462 if (user->curauthreq == user->maxauthreq) 05463 authreq_restrict = 1; 05464 else 05465 user->curauthreq++; 05466 user = user_unref(user); 05467 } 05468 } 05469 05470 /* If the AUTHREQ limit test failed, send back an error */ 05471 if (authreq_restrict) { 05472 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 05473 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 05474 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 05475 return 0; 05476 } 05477 05478 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 05479 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 05480 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 05481 ast_string_field_set(p, challenge, challenge); 05482 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 05483 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 05484 } 05485 if (p->encmethods) 05486 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 05487 05488 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 05489 05490 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 05491 05492 if (p->encmethods) 05493 ast_set_flag(p, IAX_ENCRYPTED); 05494 05495 return res; 05496 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5498 of file chan_iax2.c.
References ao2_find(), ast_atomic_fetchadd_int(), ast_check_signature, ast_clear_flag, ast_copy_string(), ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, chan_iax2_pvt::authmethods, chan_iax2_pvt::challenge, iax2_user::curauthreq, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, ies, chan_iax2_pvt::inkeys, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), iax2_user::name, chan_iax2_pvt::secret, secret, chan_iax2_pvt::state, user_unref(), and chan_iax2_pvt::username.
Referenced by socket_process().
05499 { 05500 char requeststr[256]; 05501 char md5secret[256] = ""; 05502 char secret[256] = ""; 05503 char rsasecret[256] = ""; 05504 int res = -1; 05505 int x; 05506 struct iax2_user *user, tmp_user = { 05507 .name = p->username, 05508 }; 05509 05510 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05511 if (user) { 05512 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05513 ast_atomic_fetchadd_int(&user->curauthreq, -1); 05514 ast_clear_flag(p, IAX_MAXAUTHREQ); 05515 } 05516 ast_string_field_set(p, host, user->name); 05517 user = user_unref(user); 05518 } 05519 05520 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 05521 return res; 05522 if (ies->password) 05523 ast_copy_string(secret, ies->password, sizeof(secret)); 05524 if (ies->md5_result) 05525 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05526 if (ies->rsa_result) 05527 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05528 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 05529 struct ast_key *key; 05530 char *keyn; 05531 char tmpkey[256]; 05532 char *stringp=NULL; 05533 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 05534 stringp=tmpkey; 05535 keyn = strsep(&stringp, ":"); 05536 while(keyn) { 05537 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05538 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 05539 res = 0; 05540 break; 05541 } else if (!key) 05542 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 05543 keyn = strsep(&stringp, ":"); 05544 } 05545 } else if (p->authmethods & IAX_AUTH_MD5) { 05546 struct MD5Context md5; 05547 unsigned char digest[16]; 05548 char *tmppw, *stringp; 05549 05550 tmppw = ast_strdupa(p->secret); 05551 stringp = tmppw; 05552 while((tmppw = strsep(&stringp, ";"))) { 05553 MD5Init(&md5); 05554 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 05555 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05556 MD5Final(digest, &md5); 05557 /* If they support md5, authenticate with it. */ 05558 for (x=0;x<16;x++) 05559 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05560 if (!strcasecmp(requeststr, md5secret)) { 05561 res = 0; 05562 break; 05563 } 05564 } 05565 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 05566 if (!strcmp(secret, p->secret)) 05567 res = 0; 05568 } 05569 return res; 05570 }
static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 3187 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), and sip_call().
03188 { 03189 #ifdef SCHED_MULTITHREADED 03190 if (schedule_action(__auto_congest, data)) 03191 #endif 03192 __auto_congest(data); 03193 return 0; 03194 }
static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 6540 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().
06541 { 06542 int callno = (int)(long)(data); 06543 ast_mutex_lock(&iaxsl[callno]); 06544 if (iaxs[callno]) { 06545 iaxs[callno]->autoid = -1; 06546 } 06547 ast_mutex_unlock(&iaxsl[callno]); 06548 #ifdef SCHED_MULTITHREADED 06549 if (schedule_action(__auto_hangup, data)) 06550 #endif 06551 __auto_hangup(data); 06552 return 0; 06553 }
static struct iax2_context* build_context | ( | char * | context | ) | [static] |
Definition at line 9289 of file chan_iax2.c.
References ast_calloc, and ast_copy_string().
Referenced by build_user().
09290 { 09291 struct iax2_context *con; 09292 09293 if ((con = ast_calloc(1, sizeof(*con)))) 09294 ast_copy_string(con->context, context, sizeof(con->context)); 09295 09296 return con; 09297 }
static void build_enc_keys | ( | const unsigned char * | digest, | |
aes_encrypt_ctx * | ecx, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 4220 of file chan_iax2.c.
References aes_decrypt_key128(), and aes_encrypt_key128().
Referenced by authenticate(), and decrypt_frame().
04221 { 04222 aes_encrypt_key128(digest, ecx); 04223 aes_decrypt_key128(digest, dcx); 04224 }
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 9436 of file chan_iax2.c.
References ao2_alloc(), ao2_find(), ast_append_ha(), ast_callerid_split(), ast_clear_flag, ast_copy_flags, ast_dnsmgr_lookup(), ast_free_ha(), ast_get_ip(), ast_log(), ast_parse_allow_disallow(), AST_SCHED_DEL, ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), cid_name, cid_num, iax2_peer::dbsecret, 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, iax2_peer::inkeys, ast_variable::lineno, LOG_NOTICE, LOG_WARNING, mailbox, ast_variable::name, iax2_peer::name, ast_variable::next, iax2_peer::outkey, peer_destructor(), peer_set_srcaddr(), peer_unref(), iax2_peer::peercontext, prefs, iax2_peer::regexten, S_OR, sched, secret, unlink_peer(), ast_variable::value, and zonetag.
09437 { 09438 struct iax2_peer *peer = NULL; 09439 struct ast_ha *oldha = NULL; 09440 int maskfound=0; 09441 int found=0; 09442 int firstpass=1; 09443 struct iax2_peer tmp_peer = { 09444 .name = name, 09445 }; 09446 09447 if (!temponly) { 09448 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 09449 if (peer && !ast_test_flag(peer, IAX_DELME)) 09450 firstpass = 0; 09451 } 09452 09453 if (peer) { 09454 found++; 09455 if (firstpass) { 09456 oldha = peer->ha; 09457 peer->ha = NULL; 09458 } 09459 unlink_peer(peer); 09460 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 09461 peer->expire = -1; 09462 peer->pokeexpire = -1; 09463 peer->sockfd = defaultsockfd; 09464 if (ast_string_field_init(peer, 32)) 09465 peer = peer_unref(peer); 09466 } 09467 09468 if (peer) { 09469 if (firstpass) { 09470 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09471 peer->encmethods = iax2_encryption; 09472 peer->adsi = adsi; 09473 ast_string_field_set(peer,secret,""); 09474 if (!found) { 09475 ast_string_field_set(peer, name, name); 09476 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09477 peer->expiry = min_reg_expire; 09478 } 09479 peer->prefs = prefs; 09480 peer->capability = iax2_capability; 09481 peer->smoothing = 0; 09482 peer->pokefreqok = DEFAULT_FREQ_OK; 09483 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 09484 ast_string_field_set(peer,context,""); 09485 ast_string_field_set(peer,peercontext,""); 09486 ast_clear_flag(peer, IAX_HASCALLERID); 09487 ast_string_field_set(peer, cid_name, ""); 09488 ast_string_field_set(peer, cid_num, ""); 09489 } 09490 09491 if (!v) { 09492 v = alt; 09493 alt = NULL; 09494 } 09495 while(v) { 09496 if (!strcasecmp(v->name, "secret")) { 09497 ast_string_field_set(peer, secret, v->value); 09498 } else if (!strcasecmp(v->name, "mailbox")) { 09499 ast_string_field_set(peer, mailbox, v->value); 09500 } else if (!strcasecmp(v->name, "hasvoicemail")) { 09501 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 09502 ast_string_field_set(peer, mailbox, name); 09503 } 09504 } else if (!strcasecmp(v->name, "mohinterpret")) { 09505 ast_string_field_set(peer, mohinterpret, v->value); 09506 } else if (!strcasecmp(v->name, "mohsuggest")) { 09507 ast_string_field_set(peer, mohsuggest, v->value); 09508 } else if (!strcasecmp(v->name, "dbsecret")) { 09509 ast_string_field_set(peer, dbsecret, v->value); 09510 } else if (!strcasecmp(v->name, "trunk")) { 09511 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 09512 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) { 09513 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without timing\n", peer->name); 09514 ast_clear_flag(peer, IAX_TRUNK); 09515 } 09516 } else if (!strcasecmp(v->name, "auth")) { 09517 peer->authmethods = get_auth_methods(v->value); 09518 } else if (!strcasecmp(v->name, "encryption")) { 09519 peer->encmethods = get_encrypt_methods(v->value); 09520 } else if (!strcasecmp(v->name, "notransfer")) { 09521 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09522 ast_clear_flag(peer, IAX_TRANSFERMEDIA); 09523 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 09524 } else if (!strcasecmp(v->name, "transfer")) { 09525 if (!strcasecmp(v->value, "mediaonly")) { 09526 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09527 } else if (ast_true(v->value)) { 09528 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09529 } else 09530 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09531 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09532 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 09533 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09534 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 09535 } else if (!strcasecmp(v->name, "host")) { 09536 if (!strcasecmp(v->value, "dynamic")) { 09537 /* They'll register with us */ 09538 ast_set_flag(peer, IAX_DYNAMIC); 09539 if (!found) { 09540 /* Initialize stuff iff we're not found, otherwise 09541 we keep going with what we had */ 09542 memset(&peer->addr.sin_addr, 0, 4); 09543 if (peer->addr.sin_port) { 09544 /* If we've already got a port, make it the default rather than absolute */ 09545 peer->defaddr.sin_port = peer->addr.sin_port; 09546 peer->addr.sin_port = 0; 09547 } 09548 } 09549 } else { 09550 /* Non-dynamic. Make sure we become that way if we're not */ 09551 AST_SCHED_DEL(sched, peer->expire); 09552 ast_clear_flag(peer, IAX_DYNAMIC); 09553 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) 09554 return peer_unref(peer); 09555 if (!peer->addr.sin_port) 09556 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09557 } 09558 if (!maskfound) 09559 inet_aton("255.255.255.255", &peer->mask); 09560 } else if (!strcasecmp(v->name, "defaultip")) { 09561 if (ast_get_ip(&peer->defaddr, v->value)) 09562 return peer_unref(peer); 09563 } else if (!strcasecmp(v->name, "sourceaddress")) { 09564 peer_set_srcaddr(peer, v->value); 09565 } else if (!strcasecmp(v->name, "permit") || 09566 !strcasecmp(v->name, "deny")) { 09567 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 09568 } else if (!strcasecmp(v->name, "mask")) { 09569 maskfound++; 09570 inet_aton(v->value, &peer->mask); 09571 } else if (!strcasecmp(v->name, "context")) { 09572 ast_string_field_set(peer, context, v->value); 09573 } else if (!strcasecmp(v->name, "regexten")) { 09574 ast_string_field_set(peer, regexten, v->value); 09575 } else if (!strcasecmp(v->name, "peercontext")) { 09576 ast_string_field_set(peer, peercontext, v->value); 09577 } else if (!strcasecmp(v->name, "port")) { 09578 if (ast_test_flag(peer, IAX_DYNAMIC)) 09579 peer->defaddr.sin_port = htons(atoi(v->value)); 09580 else 09581 peer->addr.sin_port = htons(atoi(v->value)); 09582 } else if (!strcasecmp(v->name, "username")) { 09583 ast_string_field_set(peer, username, v->value); 09584 } else if (!strcasecmp(v->name, "allow")) { 09585 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 09586 } else if (!strcasecmp(v->name, "disallow")) { 09587 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 09588 } else if (!strcasecmp(v->name, "callerid")) { 09589 if (!ast_strlen_zero(v->value)) { 09590 char name2[80]; 09591 char num2[80]; 09592 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 09593 ast_string_field_set(peer, cid_name, name2); 09594 ast_string_field_set(peer, cid_num, num2); 09595 } else { 09596 ast_string_field_set(peer, cid_name, ""); 09597 ast_string_field_set(peer, cid_num, ""); 09598 } 09599 ast_set_flag(peer, IAX_HASCALLERID); 09600 } else if (!strcasecmp(v->name, "fullname")) { 09601 ast_string_field_set(peer, cid_name, S_OR(v->value, "")); 09602 ast_set_flag(peer, IAX_HASCALLERID); 09603 } else if (!strcasecmp(v->name, "cid_number")) { 09604 ast_string_field_set(peer, cid_num, S_OR(v->value, "")); 09605 ast_set_flag(peer, IAX_HASCALLERID); 09606 } else if (!strcasecmp(v->name, "sendani")) { 09607 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 09608 } else if (!strcasecmp(v->name, "inkeys")) { 09609 ast_string_field_set(peer, inkeys, v->value); 09610 } else if (!strcasecmp(v->name, "outkey")) { 09611 ast_string_field_set(peer, outkey, v->value); 09612 } else if (!strcasecmp(v->name, "qualify")) { 09613 if (!strcasecmp(v->value, "no")) { 09614 peer->maxms = 0; 09615 } else if (!strcasecmp(v->value, "yes")) { 09616 peer->maxms = DEFAULT_MAXMS; 09617 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 09618 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); 09619 peer->maxms = 0; 09620 } 09621 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 09622 peer->smoothing = ast_true(v->value); 09623 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 09624 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) { 09625 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); 09626 } 09627 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 09628 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) { 09629 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); 09630 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 09631 } else if (!strcasecmp(v->name, "timezone")) { 09632 ast_string_field_set(peer, zonetag, v->value); 09633 } else if (!strcasecmp(v->name, "adsi")) { 09634 peer->adsi = ast_true(v->value); 09635 }/* else if (strcasecmp(v->name,"type")) */ 09636 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09637 v = v->next; 09638 if (!v) { 09639 v = alt; 09640 alt = NULL; 09641 } 09642 } 09643 if (!peer->authmethods) 09644 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09645 ast_clear_flag(peer, IAX_DELME); 09646 /* Make sure these are IPv4 addresses */ 09647 peer->addr.sin_family = AF_INET; 09648 } 09649 if (oldha) 09650 ast_free_ha(oldha); 09651 return peer; 09652 }
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 9668 of file chan_iax2.c.
References iax2_user::adsi, iax2_user::amaflags, ao2_alloc(), ao2_find(), ao2_unlink(), ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_free_ha(), ast_log(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_strdupa, ast_string_field_build, ast_string_field_free_memory, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), iax2_user::authmethods, build_context(), iax2_user::capability, iax2_user::cid_name, cid_name, iax2_user::cid_num, cid_num, cleanup(), iax2_user::contexts, iax2_user::curauthreq, iax2_user::dbsecret, 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, iax2_user::inkeys, ast_variable::lineno, LOG_NOTICE, LOG_WARNING, iax2_user::maxauthreq, ast_variable::name, iax2_user::name, ast_variable::next, iax2_user::prefs, prefs, secret, iax2_user::secret, user_destructor(), user_unref(), ast_variable::value, and iax2_user::vars.
09669 { 09670 struct iax2_user *user = NULL; 09671 struct iax2_context *con, *conl = NULL; 09672 struct ast_ha *oldha = NULL; 09673 struct iax2_context *oldcon = NULL; 09674 int format; 09675 int firstpass=1; 09676 int oldcurauthreq = 0; 09677 char *varname = NULL, *varval = NULL; 09678 struct ast_variable *tmpvar = NULL; 09679 struct iax2_user tmp_user = { 09680 .name = name, 09681 }; 09682 09683 if (!temponly) { 09684 user = ao2_find(users, &tmp_user, OBJ_POINTER); 09685 if (user && !ast_test_flag(user, IAX_DELME)) 09686 firstpass = 0; 09687 } 09688 09689 if (user) { 09690 if (firstpass) { 09691 oldcurauthreq = user->curauthreq; 09692 oldha = user->ha; 09693 oldcon = user->contexts; 09694 user->ha = NULL; 09695 user->contexts = NULL; 09696 } 09697 /* Already in the list, remove it and it will be added back (or FREE'd) */ 09698 ao2_unlink(users, user); 09699 } else { 09700 user = ao2_alloc(sizeof(*user), user_destructor); 09701 } 09702 09703 if (user) { 09704 if (firstpass) { 09705 ast_string_field_free_memory(user); 09706 memset(user, 0, sizeof(struct iax2_user)); 09707 if (ast_string_field_init(user, 32)) { 09708 user = user_unref(user); 09709 goto cleanup; 09710 } 09711 user->maxauthreq = maxauthreq; 09712 user->curauthreq = oldcurauthreq; 09713 user->prefs = prefs; 09714 user->capability = iax2_capability; 09715 user->encmethods = iax2_encryption; 09716 user->adsi = adsi; 09717 ast_string_field_set(user, name, name); 09718 ast_string_field_set(user, language, language); 09719 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 09720 ast_clear_flag(user, IAX_HASCALLERID); 09721 ast_string_field_set(user, cid_name, ""); 09722 ast_string_field_set(user, cid_num, ""); 09723 } 09724 if (!v) { 09725 v = alt; 09726 alt = NULL; 09727 } 09728 while(v) { 09729 if (!strcasecmp(v->name, "context")) { 09730 con = build_context(v->value); 09731 if (con) { 09732 if (conl) 09733 conl->next = con; 09734 else 09735 user->contexts = con; 09736 conl = con; 09737 } 09738 } else if (!strcasecmp(v->name, "permit") || 09739 !strcasecmp(v->name, "deny")) { 09740 user->ha = ast_append_ha(v->name, v->value, user->ha); 09741 } else if (!strcasecmp(v->name, "setvar")) { 09742 varname = ast_strdupa(v->value); 09743 if (varname && (varval = strchr(varname,'='))) { 09744 *varval = '\0'; 09745 varval++; 09746 if((tmpvar = ast_variable_new(varname, varval))) { 09747 tmpvar->next = user->vars; 09748 user->vars = tmpvar; 09749 } 09750 } 09751 } else if (!strcasecmp(v->name, "allow")) { 09752 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 09753 } else if (!strcasecmp(v->name, "disallow")) { 09754 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 09755 } else if (!strcasecmp(v->name, "trunk")) { 09756 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 09757 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) { 09758 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without timing\n", user->name); 09759 ast_clear_flag(user, IAX_TRUNK); 09760 } 09761 } else if (!strcasecmp(v->name, "auth")) { 09762 user->authmethods = get_auth_methods(v->value); 09763 } else if (!strcasecmp(v->name, "encryption")) { 09764 user->encmethods = get_encrypt_methods(v->value); 09765 } else if (!strcasecmp(v->name, "notransfer")) { 09766 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09767 ast_clear_flag(user, IAX_TRANSFERMEDIA); 09768 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 09769 } else if (!strcasecmp(v->name, "transfer")) { 09770 if (!strcasecmp(v->value, "mediaonly")) { 09771 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09772 } else if (ast_true(v->value)) { 09773 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09774 } else 09775 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09776 } else if (!strcasecmp(v->name, "codecpriority")) { 09777 if(!strcasecmp(v->value, "caller")) 09778 ast_set_flag(user, IAX_CODEC_USER_FIRST); 09779 else if(!strcasecmp(v->value, "disabled")) 09780 ast_set_flag(user, IAX_CODEC_NOPREFS); 09781 else if(!strcasecmp(v->value, "reqonly")) { 09782 ast_set_flag(user, IAX_CODEC_NOCAP); 09783 ast_set_flag(user, IAX_CODEC_NOPREFS); 09784 } 09785 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09786 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 09787 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09788 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 09789 } else if (!strcasecmp(v->name, "dbsecret")) { 09790 ast_string_field_set(user, dbsecret, v->value); 09791 } else if (!strcasecmp(v->name, "secret")) { 09792 if (!ast_strlen_zero(user->secret)) { 09793 char *old = ast_strdupa(user->secret); 09794 09795 ast_string_field_build(user, secret, "%s;%s", old, v->value); 09796 } else 09797 ast_string_field_set(user, secret, v->value); 09798 } else if (!strcasecmp(v->name, "callerid")) { 09799 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 09800 char name2[80]; 09801 char num2[80]; 09802 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 09803 ast_string_field_set(user, cid_name, name2); 09804 ast_string_field_set(user, cid_num, num2); 09805 ast_set_flag(user, IAX_HASCALLERID); 09806 } else { 09807 ast_clear_flag(user, IAX_HASCALLERID); 09808 ast_string_field_set(user, cid_name, ""); 09809 ast_string_field_set(user, cid_num, ""); 09810 } 09811 } else if (!strcasecmp(v->name, "fullname")) { 09812 if (!ast_strlen_zero(v->value)) { 09813 ast_string_field_set(user, cid_name, v->value); 09814 ast_set_flag(user, IAX_HASCALLERID); 09815 } else { 09816 ast_string_field_set(user, cid_name, ""); 09817 if (ast_strlen_zero(user->cid_num)) 09818 ast_clear_flag(user, IAX_HASCALLERID); 09819 } 09820 } else if (!strcasecmp(v->name, "cid_number")) { 09821 if (!ast_strlen_zero(v->value)) { 09822 ast_string_field_set(user, cid_num, v->value); 09823 ast_set_flag(user, IAX_HASCALLERID); 09824 } else { 09825 ast_string_field_set(user, cid_num, ""); 09826 if (ast_strlen_zero(user->cid_name)) 09827 ast_clear_flag(user, IAX_HASCALLERID); 09828 } 09829 } else if (!strcasecmp(v->name, "accountcode")) { 09830 ast_string_field_set(user, accountcode, v->value); 09831 } else if (!strcasecmp(v->name, "mohinterpret")) { 09832 ast_string_field_set(user, mohinterpret, v->value); 09833 } else if (!strcasecmp(v->name, "mohsuggest")) { 09834 ast_string_field_set(user, mohsuggest, v->value); 09835 } else if (!strcasecmp(v->name, "language")) { 09836 ast_string_field_set(user, language, v->value); 09837 } else if (!strcasecmp(v->name, "amaflags")) { 09838 format = ast_cdr_amaflags2int(v->value); 09839 if (format < 0) { 09840 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 09841 } else { 09842 user->amaflags = format; 09843 } 09844 } else if (!strcasecmp(v->name, "inkeys")) { 09845 ast_string_field_set(user, inkeys, v->value); 09846 } else if (!strcasecmp(v->name, "maxauthreq")) { 09847 user->maxauthreq = atoi(v->value); 09848 if (user->maxauthreq < 0) 09849 user->maxauthreq = 0; 09850 } else if (!strcasecmp(v->name, "adsi")) { 09851 user->adsi = ast_true(v->value); 09852 }/* else if (strcasecmp(v->name,"type")) */ 09853 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09854 v = v->next; 09855 if (!v) { 09856 v = alt; 09857 alt = NULL; 09858 } 09859 } 09860 if (!user->authmethods) { 09861 if (!ast_strlen_zero(user->secret)) { 09862 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09863 if (!ast_strlen_zero(user->inkeys)) 09864 user->authmethods |= IAX_AUTH_RSA; 09865 } else if (!ast_strlen_zero(user->inkeys)) { 09866 user->authmethods = IAX_AUTH_RSA; 09867 } else { 09868 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09869 } 09870 } 09871 ast_clear_flag(user, IAX_DELME); 09872 } 09873 cleanup: 09874 if (oldha) 09875 ast_free_ha(oldha); 09876 if (oldcon) 09877 free_context(oldcon); 09878 return user; 09879 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 10385 of file chan_iax2.c.
References ARRAY_LEN, AST_FRAME_IAX, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), chan_iax2_pvt::capability, create_addr(), find_callno_locked(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_COMMAND_NEW, iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CAPABILITY, IAX_IE_FORMAT, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, iaxs, iaxsl, LOG_WARNING, NEW_FORCE, option_debug, parse_dial_string(), secret, and send_command().
Referenced by find_cache().
10386 { 10387 struct sockaddr_in sin; 10388 int x; 10389 int callno; 10390 struct iax_ie_data ied; 10391 struct create_addr_info cai; 10392 struct parsed_dial_string pds; 10393 char *tmpstr; 10394 10395 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 10396 /* Look for an *exact match* call. Once a call is negotiated, it can only 10397 look up entries for a single context */ 10398 if (!ast_mutex_trylock(&iaxsl[x])) { 10399 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 10400 return x; 10401 ast_mutex_unlock(&iaxsl[x]); 10402 } 10403 } 10404 10405 /* No match found, we need to create a new one */ 10406 10407 memset(&cai, 0, sizeof(cai)); 10408 memset(&ied, 0, sizeof(ied)); 10409 memset(&pds, 0, sizeof(pds)); 10410 10411 tmpstr = ast_strdupa(data); 10412 parse_dial_string(tmpstr, &pds); 10413 10414 if (ast_strlen_zero(pds.peer)) { 10415 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 10416 return -1; 10417 } 10418 10419 /* Populate our address from the given */ 10420 if (create_addr(pds.peer, NULL, &sin, &cai)) 10421 return -1; 10422 10423 if (option_debug) 10424 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n", 10425 pds.peer, pds.username, pds.password, pds.context); 10426 10427 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 10428 if (callno < 1) { 10429 ast_log(LOG_WARNING, "Unable to create call\n"); 10430 return -1; 10431 } 10432 10433 ast_string_field_set(iaxs[callno], dproot, data); 10434 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 10435 10436 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 10437 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 10438 /* the string format is slightly different from a standard dial string, 10439 because the context appears in the 'exten' position 10440 */ 10441 if (pds.exten) 10442 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 10443 if (pds.username) 10444 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 10445 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 10446 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 10447 /* Keep password handy */ 10448 if (pds.password) 10449 ast_string_field_set(iaxs[callno], secret, pds.password); 10450 if (pds.key) 10451 ast_string_field_set(iaxs[callno], outkey, pds.key); 10452 /* Start the call going */ 10453 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 10454 10455 return callno; 10456 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 4088 of file chan_iax2.c.
References ast_log(), ast_random(), ast_samp2tv(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chan_iax2_pvt::callno, option_debug, and chan_iax2_pvt::rxcore.
04089 { 04090 /* Returns where in "receive time" we are. That is, how many ms 04091 since we received (or would have received) the frame with timestamp 0 */ 04092 int ms; 04093 #ifdef IAXTESTS 04094 int jit; 04095 #endif /* IAXTESTS */ 04096 /* Setup rxcore if necessary */ 04097 if (ast_tvzero(p->rxcore)) { 04098 p->rxcore = ast_tvnow(); 04099 if (option_debug && iaxdebug) 04100 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 04101 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 04102 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 04103 #if 1 04104 if (option_debug && iaxdebug) 04105 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 04106 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 04107 #endif 04108 } 04109 04110 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 04111 #ifdef IAXTESTS 04112 if (test_jit) { 04113 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 04114 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 04115 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 04116 jit = -jit; 04117 ms += jit; 04118 } 04119 } 04120 if (test_late) { 04121 ms += test_late; 04122 test_late = 0; 04123 } 04124 #endif /* IAXTESTS */ 04125 return ms; 04126 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 3959 of file chan_iax2.c.
References AST_FRAME_CNG, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_samp2tv(), ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chan_iax2_pvt::callno, f, iaxs, chan_iax2_pvt::lastsent, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, chan_iax2_pvt::offset, and option_debug.
Referenced by iax2_send(), and socket_process().
03960 { 03961 int ms; 03962 int voice = 0; 03963 int genuine = 0; 03964 int adjust; 03965 struct timeval *delivery = NULL; 03966 03967 03968 /* What sort of frame do we have?: voice is self-explanatory 03969 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 03970 non-genuine frames are CONTROL frames [ringing etc], DTMF 03971 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 03972 the others need a timestamp slaved to the voice frames so that they go in sequence 03973 */ 03974 if (f) { 03975 if (f->frametype == AST_FRAME_VOICE) { 03976 voice = 1; 03977 delivery = &f->delivery; 03978 } else if (f->frametype == AST_FRAME_IAX) { 03979 genuine = 1; 03980 } else if (f->frametype == AST_FRAME_CNG) { 03981 p->notsilenttx = 0; 03982 } 03983 } 03984 if (ast_tvzero(p->offset)) { 03985 gettimeofday(&p->offset, NULL); 03986 /* Round to nearest 20ms for nice looking traces */ 03987 p->offset.tv_usec -= p->offset.tv_usec % 20000; 03988 } 03989 /* If the timestamp is specified, just send it as is */ 03990 if (ts) 03991 return ts; 03992 /* If we have a time that the frame arrived, always use it to make our timestamp */ 03993 if (delivery && !ast_tvzero(*delivery)) { 03994 ms = ast_tvdiff_ms(*delivery, p->offset); 03995 if (option_debug > 2 && iaxdebug) 03996 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 03997 } else { 03998 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 03999 if (ms < 0) 04000 ms = 0; 04001 if (voice) { 04002 /* On a voice frame, use predicted values if appropriate */ 04003 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 04004 /* Adjust our txcore, keeping voice and non-voice synchronized */ 04005 /* AN EXPLANATION: 04006 When we send voice, we usually send "calculated" timestamps worked out 04007 on the basis of the number of samples sent. When we send other frames, 04008 we usually send timestamps worked out from the real clock. 04009 The problem is that they can tend to drift out of step because the 04010 source channel's clock and our clock may not be exactly at the same rate. 04011 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 04012 for this call. Moving it adjusts timestamps for non-voice frames. 04013 We make the adjustment in the style of a moving average. Each time we 04014 adjust p->offset by 10% of the difference between our clock-derived 04015 timestamp and the predicted timestamp. That's why you see "10000" 04016 below even though IAX2 timestamps are in milliseconds. 04017 The use of a moving average avoids offset moving too radically. 04018 Generally, "adjust" roams back and forth around 0, with offset hardly 04019 changing at all. But if a consistent different starts to develop it 04020 will be eliminated over the course of 10 frames (200-300msecs) 04021 */ 04022 adjust = (ms - p->nextpred); 04023 if (adjust < 0) 04024 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 04025 else if (adjust > 0) 04026 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 04027 04028 if (!p->nextpred) { 04029 p->nextpred = ms; /*f->samples / 8;*/ 04030 if (p->nextpred <= p->lastsent) 04031 p->nextpred = p->lastsent + 3; 04032 } 04033 ms = p->nextpred; 04034 } else { 04035 /* in this case, just use the actual 04036 * time, since we're either way off 04037 * (shouldn't happen), or we're ending a 04038 * silent period -- and seed the next 04039 * predicted time. Also, round ms to the 04040 * next multiple of frame size (so our 04041 * silent periods are multiples of 04042 * frame size too) */ 04043 04044 if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 04045 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 04046 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 04047 04048 if (f->samples >= 8) /* check to make sure we dont core dump */ 04049 { 04050 int diff = ms % (f->samples / 8); 04051 if (diff) 04052 ms += f->samples/8 - diff; 04053 } 04054 04055 p->nextpred = ms; 04056 p->notsilenttx = 1; 04057 } 04058 } else if ( f->frametype == AST_FRAME_VIDEO ) { 04059 /* 04060 * IAX2 draft 03 says that timestamps MUST be in order. 04061 * It does not say anything about several frames having the same timestamp 04062 * When transporting video, we can have a frame that spans multiple iax packets 04063 * (so called slices), so it would make sense to use the same timestamp for all of 04064 * them 04065 * We do want to make sure that frames don't go backwards though 04066 */ 04067 if ( (unsigned int)ms < p->lastsent ) 04068 ms = p->lastsent; 04069 } else { 04070 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 04071 it's a genuine frame */ 04072 if (genuine) { 04073 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 04074 if (ms <= p->lastsent) 04075 ms = p->lastsent + 3; 04076 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 04077 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 04078 ms = p->lastsent + 3; 04079 } 04080 } 04081 } 04082 p->lastsent = ms; 04083 if (voice) 04084 p->nextpred = p->nextpred + f->samples / 8; 04085 return ms; 04086 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | tv | |||
) | [static] |
Definition at line 3915 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvzero(), iax2_trunk_peer::lastsent, iax2_trunk_peer::lasttxtime, MAX_TIMESTAMP_SKEW, iax2_trunk_peer::trunkact, and iax2_trunk_peer::txtrunktime.
Referenced by send_trunk().
03916 { 03917 unsigned long int mssincetx; /* unsigned to handle overflows */ 03918 long int ms, pred; 03919 03920 tpeer->trunkact = *tv; 03921 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime); 03922 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 03923 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 03924 tpeer->txtrunktime = *tv; 03925 tpeer->lastsent = 999999; 03926 } 03927 /* Update last transmit time now */ 03928 tpeer->lasttxtime = *tv; 03929 03930 /* Calculate ms offset */ 03931 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime); 03932 /* Predict from last value */ 03933 pred = tpeer->lastsent + sampms; 03934 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 03935 ms = pred; 03936 03937 /* We never send the same timestamp twice, so fudge a little if we must */ 03938 if (ms == tpeer->lastsent) 03939 ms = tpeer->lastsent + 1; 03940 tpeer->lastsent = ms; 03941 return ms; 03942 }
static int check_access | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5199 of file chan_iax2.c.
References iax2_user::accountcode, 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, iax2_user::cid_name, cid_name, iax2_user::cid_num, cid_num, iax2_context::context, chan_iax2_pvt::context, iax2_user::contexts, iax2_user::dbsecret, 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, iax2_user::inkeys, iax2_user::language, LOG_WARNING, iax2_user::maxauthreq, iax2_user::mohinterpret, iax2_user::mohsuggest, ast_variable::name, iax2_user::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, iax2_user::secret, user_unref(), ast_variable::value, chan_iax2_pvt::vars, and iax2_user::vars.
Referenced by socket_process().
05200 { 05201 /* Start pessimistic */ 05202 int res = -1; 05203 int version = 2; 05204 struct iax2_user *user = NULL, *best = NULL; 05205 int bestscore = 0; 05206 int gotcapability = 0; 05207 struct ast_variable *v = NULL, *tmpvar = NULL; 05208 struct ao2_iterator i; 05209 05210 if (!iaxs[callno]) 05211 return res; 05212 if (ies->called_number) 05213 ast_string_field_set(iaxs[callno], exten, ies->called_number); 05214 if (ies->calling_number) { 05215 ast_shrink_phone_number(ies->calling_number); 05216 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 05217 } 05218 if (ies->calling_name) 05219 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 05220 if (ies->calling_ani) 05221 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 05222 if (ies->dnid) 05223 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 05224 if (ies->rdnis) 05225 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 05226 if (ies->called_context) 05227 ast_string_field_set(iaxs[callno], context, ies->called_context); 05228 if (ies->language) 05229 ast_string_field_set(iaxs[callno], language, ies->language); 05230 if (ies->username) 05231 ast_string_field_set(iaxs[callno], username, ies->username); 05232 if (ies->calling_ton > -1) 05233 iaxs[callno]->calling_ton = ies->calling_ton; 05234 if (ies->calling_tns > -1) 05235 iaxs[callno]->calling_tns = ies->calling_tns; 05236 if (ies->calling_pres > -1) 05237 iaxs[callno]->calling_pres = ies->calling_pres; 05238 if (ies->format) 05239 iaxs[callno]->peerformat = ies->format; 05240 if (ies->adsicpe) 05241 iaxs[callno]->peeradsicpe = ies->adsicpe; 05242 if (ies->capability) { 05243 gotcapability = 1; 05244 iaxs[callno]->peercapability = ies->capability; 05245 } 05246 if (ies->version) 05247 version = ies->version; 05248 05249 /* Use provided preferences until told otherwise for actual preferences */ 05250 if(ies->codec_prefs) { 05251 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 05252 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 05253 } 05254 05255 if (!gotcapability) 05256 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 05257 if (version > IAX_PROTO_VERSION) { 05258 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 05259 ast_inet_ntoa(sin->sin_addr), version); 05260 return res; 05261 } 05262 /* Search the userlist for a compatible entry, and fill in the rest */ 05263 i = ao2_iterator_init(users, 0); 05264 while ((user = ao2_iterator_next(&i))) { 05265 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 05266 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 05267 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 05268 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 05269 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 05270 if (!ast_strlen_zero(iaxs[callno]->username)) { 05271 /* Exact match, stop right now. */ 05272 if (best) 05273 user_unref(best); 05274 best = user; 05275 break; 05276 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 05277 /* No required authentication */ 05278 if (user->ha) { 05279 /* There was host authentication and we passed, bonus! */ 05280 if (bestscore < 4) { 05281 bestscore = 4; 05282 if (best) 05283 user_unref(best); 05284 best = user; 05285 continue; 05286 } 05287 } else { 05288 /* No host access, but no secret, either, not bad */ 05289 if (bestscore < 3) { 05290 bestscore = 3; 05291 if (best) 05292 user_unref(best); 05293 best = user; 05294 continue; 05295 } 05296 } 05297 } else { 05298 if (user->ha) { 05299 /* Authentication, but host access too, eh, it's something.. */ 05300 if (bestscore < 2) { 05301 bestscore = 2; 05302 if (best) 05303 user_unref(best); 05304 best = user; 05305 continue; 05306 } 05307 } else { 05308 /* Authentication and no host access... This is our baseline */ 05309 if (bestscore < 1) { 05310 bestscore = 1; 05311 if (best) 05312 user_unref(best); 05313 best = user; 05314 continue; 05315 } 05316 } 05317 } 05318 } 05319 user_unref(user); 05320 } 05321 user = best; 05322 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 05323 user = realtime_user(iaxs[callno]->username, sin); 05324 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 05325 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 05326 user = user_unref(user); 05327 } 05328 } 05329 if (user) { 05330 /* We found our match (use the first) */ 05331 /* copy vars */ 05332 for (v = user->vars ; v ; v = v->next) { 05333 if((tmpvar = ast_variable_new(v->name, v->value))) { 05334 tmpvar->next = iaxs[callno]->vars; 05335 iaxs[callno]->vars = tmpvar; 05336 } 05337 } 05338 /* If a max AUTHREQ restriction is in place, activate it */ 05339 if (user->maxauthreq > 0) 05340 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ); 05341 iaxs[callno]->prefs = user->prefs; 05342 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST); 05343 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS); 05344 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP); 05345 iaxs[callno]->encmethods = user->encmethods; 05346 /* Store the requested username if not specified */ 05347 if (ast_strlen_zero(iaxs[callno]->username)) 05348 ast_string_field_set(iaxs[callno], username, user->name); 05349 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 05350 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 05351 iaxs[callno]->capability = user->capability; 05352 /* And use the default context */ 05353 if (ast_strlen_zero(iaxs[callno]->context)) { 05354 if (user->contexts) 05355 ast_string_field_set(iaxs[callno], context, user->contexts->context); 05356 else 05357 ast_string_field_set(iaxs[callno], context, context); 05358 } 05359 /* And any input keys */ 05360 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 05361 /* And the permitted authentication methods */ 05362 iaxs[callno]->authmethods = user->authmethods; 05363 iaxs[callno]->adsi = user->adsi; 05364 /* If the user has callerid, override the remote caller id. */ 05365 if (ast_test_flag(user, IAX_HASCALLERID)) { 05366 iaxs[callno]->calling_tns = 0; 05367 iaxs[callno]->calling_ton = 0; 05368 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 05369 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 05370 ast_string_field_set(iaxs[callno], ani, user->cid_num); 05371 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 05372 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) { 05373 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 05374 } /* else user is allowed to set their own CID settings */ 05375 if (!ast_strlen_zero(user->accountcode)) 05376 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 05377 if (!ast_strlen_zero(user->mohinterpret)) 05378 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 05379 if (!ast_strlen_zero(user->mohsuggest)) 05380 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 05381 if (user->amaflags) 05382 iaxs[callno]->amaflags = user->amaflags; 05383 if (!ast_strlen_zero(user->language)) 05384 ast_string_field_set(iaxs[callno], language, user->language); 05385 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 05386 /* Keep this check last */ 05387 if (!ast_strlen_zero(user->dbsecret)) { 05388 char *family, *key=NULL; 05389 char buf[80]; 05390 family = ast_strdupa(user->dbsecret); 05391 key = strchr(family, '/'); 05392 if (key) { 05393 *key = '\0'; 05394 key++; 05395 } 05396 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 05397 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 05398 else 05399 ast_string_field_set(iaxs[callno], secret, buf); 05400 } else 05401 ast_string_field_set(iaxs[callno], secret, user->secret); 05402 res = 0; 05403 user = user_unref(user); 05404 } 05405 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 05406 return res; 05407 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 6898 of file chan_iax2.c.
References ast_log(), iax2_provision(), iax_provision_version(), and option_debug.
Referenced by socket_process().
06899 { 06900 unsigned int ourver; 06901 char rsi[80]; 06902 snprintf(rsi, sizeof(rsi), "si-%s", si); 06903 if (iax_provision_version(&ourver, rsi, 1)) 06904 return 0; 06905 if (option_debug) 06906 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 06907 if (ourver != ver) 06908 iax2_provision(sin, sockfd, NULL, rsi, 1); 06909 return 0; 06910 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 9315 of file chan_iax2.c.
References ast_log(), errno, LOG_ERROR, and option_debug.
Referenced by peer_set_srcaddr().
09316 { 09317 int sd; 09318 int res; 09319 09320 sd = socket(AF_INET, SOCK_DGRAM, 0); 09321 if (sd < 0) { 09322 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 09323 return -1; 09324 } 09325 09326 res = bind(sd, sa, salen); 09327 if (res < 0) { 09328 if (option_debug) 09329 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno)); 09330 close(sd); 09331 return 1; 09332 } 09333 09334 close(sd); 09335 return 0; 09336 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5892 of file chan_iax2.c.
References ARRAY_LEN, ast_copy_string(), ast_log(), 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, dpcache_lock, chan_iax2_pvt::dpentries, errno, 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, LOG_WARNING, iax2_dpcache::orig, iax2_dpcache::peer, and iax2_dpcache::waiters.
Referenced by socket_process().
05893 { 05894 char exten[256] = ""; 05895 int status = CACHE_FLAG_UNKNOWN; 05896 int expiry = iaxdefaultdpcache; 05897 int x; 05898 int matchmore = 0; 05899 struct iax2_dpcache *dp, *prev; 05900 05901 if (ies->called_number) 05902 ast_copy_string(exten, ies->called_number, sizeof(exten)); 05903 05904 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 05905 status = CACHE_FLAG_EXISTS; 05906 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 05907 status = CACHE_FLAG_CANEXIST; 05908 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 05909 status = CACHE_FLAG_NONEXISTENT; 05910 05911 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) { 05912 /* Don't really do anything with this */ 05913 } 05914 if (ies->refresh) 05915 expiry = ies->refresh; 05916 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 05917 matchmore = CACHE_FLAG_MATCHMORE; 05918 ast_mutex_lock(&dpcache_lock); 05919 prev = NULL; 05920 dp = pvt->dpentries; 05921 while(dp) { 05922 if (!strcmp(dp->exten, exten)) { 05923 /* Let them go */ 05924 if (prev) 05925 prev->peer = dp->peer; 05926 else 05927 pvt->dpentries = dp->peer; 05928 dp->peer = NULL; 05929 dp->callno = 0; 05930 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 05931 if (dp->flags & CACHE_FLAG_PENDING) { 05932 dp->flags &= ~CACHE_FLAG_PENDING; 05933 dp->flags |= status; 05934 dp->flags |= matchmore; 05935 } 05936 /* Wake up waiters */ 05937 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 05938 if (dp->waiters[x] > -1) { 05939 if (write(dp->waiters[x], "asdf", 4) < 0) { 05940 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 05941 } 05942 } 05943 } 05944 } 05945 prev = dp; 05946 dp = dp->peer; 05947 } 05948 ast_mutex_unlock(&dpcache_lock); 05949 return 0; 05950 }
static char* complete_iax2_show_peer | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2456 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_strdup, iax2_peer::name, and peer_unref().
02457 { 02458 int which = 0; 02459 struct iax2_peer *peer; 02460 char *res = NULL; 02461 int wordlen = strlen(word); 02462 struct ao2_iterator i; 02463 02464 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */ 02465 if (pos != 3) 02466 return NULL; 02467 02468 i = ao2_iterator_init(peers, 0); 02469 while ((peer = ao2_iterator_next(&i))) { 02470 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) { 02471 res = ast_strdup(peer->name); 02472 peer_unref(peer); 02473 break; 02474 } 02475 peer_unref(peer); 02476 } 02477 02478 return res; 02479 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5952 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, iax_frame::list, LOG_WARNING, chan_iax2_pvt::nextpred, chan_iax2_pvt::offset, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, ast_iax2_queue::queue, remove_by_peercallno(), iax_frame::retries, chan_iax2_pvt::rseqno, chan_iax2_pvt::rxcore, store_by_peercallno(), chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, TRANSFER_NONE, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, chan_iax2_pvt::videoformat, and chan_iax2_pvt::voiceformat.
Referenced by socket_process().
05953 { 05954 int peercallno = 0; 05955 struct chan_iax2_pvt *pvt = iaxs[callno]; 05956 struct iax_frame *cur; 05957 jb_frame frame; 05958 05959 if (ies->callno) 05960 peercallno = ies->callno; 05961 05962 if (peercallno < 1) { 05963 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05964 return -1; 05965 } 05966 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 05967 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 05968 /* Reset sequence numbers */ 05969 pvt->oseqno = 0; 05970 pvt->rseqno = 0; 05971 pvt->iseqno = 0; 05972 pvt->aseqno = 0; 05973 05974 if (pvt->peercallno) { 05975 remove_by_peercallno(pvt); 05976 } 05977 pvt->peercallno = peercallno; 05978 store_by_peercallno(pvt); 05979 05980 pvt->transferring = TRANSFER_NONE; 05981 pvt->svoiceformat = -1; 05982 pvt->voiceformat = 0; 05983 pvt->svideoformat = -1; 05984 pvt->videoformat = 0; 05985 pvt->transfercallno = -1; 05986 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 05987 memset(&pvt->offset, 0, sizeof(pvt->offset)); 05988 /* reset jitterbuffer */ 05989 while(jb_getall(pvt->jb,&frame) == JB_OK) 05990 iax2_frame_free(frame.data); 05991 jb_reset(pvt->jb); 05992 pvt->lag = 0; 05993 pvt->last = 0; 05994 pvt->lastsent = 0; 05995 pvt->nextpred = 0; 05996 pvt->pingtime = DEFAULT_RETRY_TIME; 05997 AST_LIST_LOCK(&iaxq.queue); 05998 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 05999 /* We must cancel any packets that would have been transmitted 06000 because now we're talking to someone new. It's okay, they 06001 were transmitted to someone that didn't care anyway. */ 06002 if (callno == cur->callno) 06003 cur->retries = -1; 06004 } 06005 AST_LIST_UNLOCK(&iaxq.queue); 06006 return 0; 06007 }
static unsigned char compress_subclass | ( | int | subclass | ) | [static] |
Definition at line 1073 of file chan_iax2.c.
References ast_log(), IAX_FLAG_SC_LOG, IAX_MAX_SHIFT, and LOG_WARNING.
Referenced by iax2_send(), raw_hangup(), and send_apathetic_reply().
01074 { 01075 int x; 01076 int power=-1; 01077 /* If it's 128 or smaller, just return it */ 01078 if (subclass < IAX_FLAG_SC_LOG) 01079 return subclass; 01080 /* Otherwise find its power */ 01081 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01082 if (subclass & (1 << x)) { 01083 if (power > -1) { 01084 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 01085 return 0; 01086 } else 01087 power = x; 01088 } 01089 } 01090 return power | IAX_FLAG_SC_LOG; 01091 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 6912 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().
06913 { 06914 jb_info stats; 06915 jb_getinfo(pvt->jb, &stats); 06916 06917 memset(iep, 0, sizeof(*iep)); 06918 06919 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 06920 if(stats.frames_in == 0) stats.frames_in = 1; 06921 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 06922 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 06923 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 06924 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 06925 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 06926 }
static int create_addr | ( | const char * | peername, | |
struct ast_channel * | c, | |||
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 3079 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, create_addr_info::adsi, ahp, ast_clear_flag, ast_codec_pref_convert(), ast_codec_pref_prepend(), ast_copy_flags, ast_copy_string(), ast_db_get(), ast_gethostbyname(), ast_log(), ast_strdupa, ast_strlen_zero(), iax2_peer::capability, create_addr_info::capability, iax2_peer::context, create_addr_info::context, iax2_peer::dbsecret, iax2_peer::defaddr, iax2_peer::encmethods, create_addr_info::encmethods, find_peer(), create_addr_info::found, hp, IAX_DEFAULT_PORTNO, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, create_addr_info::maxtime, iax2_peer::mohinterpret, create_addr_info::mohinterpret, iax2_peer::mohsuggest, create_addr_info::mohsuggest, ast_channel::nativeformats, iax2_peer::outkey, create_addr_info::outkey, peer_unref(), iax2_peer::peercontext, create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, prefs, iax2_peer::secret, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, create_addr_info::timezone, iax2_peer::username, create_addr_info::username, and iax2_peer::zonetag.
03080 { 03081 struct ast_hostent ahp; 03082 struct hostent *hp; 03083 struct iax2_peer *peer; 03084 int res = -1; 03085 struct ast_codec_pref ourprefs; 03086 03087 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 03088 cai->sockfd = defaultsockfd; 03089 cai->maxtime = 0; 03090 sin->sin_family = AF_INET; 03091 03092 if (!(peer = find_peer(peername, 1))) { 03093 cai->found = 0; 03094 03095 hp = ast_gethostbyname(peername, &ahp); 03096 if (hp) { 03097 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 03098 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 03099 /* use global iax prefs for unknown peer/user */ 03100 /* But move the calling channel's native codec to the top of the preference list */ 03101 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 03102 if (c) 03103 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 03104 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 03105 return 0; 03106 } else { 03107 ast_log(LOG_WARNING, "No such host: %s\n", peername); 03108 return -1; 03109 } 03110 } 03111 03112 cai->found = 1; 03113 03114 /* if the peer has no address (current or default), return failure */ 03115 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) 03116 goto return_unref; 03117 03118 /* if the peer is being monitored and is currently unreachable, return failure */ 03119 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 03120 goto return_unref; 03121 03122 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 03123 cai->maxtime = peer->maxms; 03124 cai->capability = peer->capability; 03125 cai->encmethods = peer->encmethods; 03126 cai->sockfd = peer->sockfd; 03127 cai->adsi = peer->adsi; 03128 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 03129 /* Move the calling channel's native codec to the top of the preference list */ 03130 if (c) { 03131 ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats); 03132 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 03133 } 03134 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 03135 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 03136 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 03137 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 03138 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 03139 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 03140 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 03141 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 03142 if (ast_strlen_zero(peer->dbsecret)) { 03143 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 03144 } else { 03145 char *family; 03146 char *key = NULL; 03147 03148 family = ast_strdupa(peer->dbsecret); 03149 key = strchr(family, '/'); 03150 if (key) 03151 *key++ = '\0'; 03152 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 03153 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 03154 goto return_unref; 03155 } 03156 } 03157 03158 if (peer->addr.sin_addr.s_addr) { 03159 sin->sin_addr = peer->addr.sin_addr; 03160 sin->sin_port = peer->addr.sin_port; 03161 } else { 03162 sin->sin_addr = peer->defaddr.sin_addr; 03163 sin->sin_port = peer->defaddr.sin_port; 03164 } 03165 03166 res = 0; 03167 03168 return_unref: 03169 peer_unref(peer); 03170 03171 return res; 03172 }
static int decode_frame | ( | aes_decrypt_ctx * | dcx, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 4274 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().
04275 { 04276 int padding; 04277 unsigned char *workspace; 04278 04279 workspace = alloca(*datalen); 04280 memset(f, 0, sizeof(*f)); 04281 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 04282 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 04283 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 04284 return -1; 04285 /* Decrypt */ 04286 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 04287 04288 padding = 16 + (workspace[15] & 0xf); 04289 if (option_debug && iaxdebug) 04290 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 04291 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 04292 return -1; 04293 04294 *datalen -= padding; 04295 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 04296 f->frametype = fh->type; 04297 if (f->frametype == AST_FRAME_VIDEO) { 04298 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 04299 } else { 04300 f->subclass = uncompress_subclass(fh->csub); 04301 } 04302 } else { 04303 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 04304 if (option_debug && iaxdebug) 04305 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen); 04306 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 04307 return -1; 04308 /* Decrypt */ 04309 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 04310 padding = 16 + (workspace[15] & 0x0f); 04311 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 04312 return -1; 04313 *datalen -= padding; 04314 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04315 } 04316 return 0; 04317 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 4360 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(), and secret.
Referenced by socket_process().
04361 { 04362 int res=-1; 04363 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 04364 /* Search for possible keys, given secrets */ 04365 struct MD5Context md5; 04366 unsigned char digest[16]; 04367 char *tmppw, *stringp; 04368 04369 tmppw = ast_strdupa(iaxs[callno]->secret); 04370 stringp = tmppw; 04371 while ((tmppw = strsep(&stringp, ";"))) { 04372 MD5Init(&md5); 04373 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 04374 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 04375 MD5Final(digest, &md5); 04376 build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx); 04377 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04378 if (!res) { 04379 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 04380 break; 04381 } 04382 } 04383 } else 04384 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04385 return res; 04386 }
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 6974 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(), iax2_pkt_buf::buf, iax2_thread::buf, iax2_thread::buf_len, iax2_thread::full_frames, iax2_thread::lock, and ast_iax2_full_hdr::oseqno.
Referenced by socket_read().
06975 { 06976 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 06977 struct ast_iax2_full_hdr *fh, *cur_fh; 06978 06979 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 06980 return; 06981 06982 pkt_buf->len = from_here->buf_len; 06983 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 06984 06985 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 06986 ast_mutex_lock(&to_here->lock); 06987 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 06988 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 06989 if (fh->oseqno < cur_fh->oseqno) { 06990 AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry); 06991 break; 06992 } 06993 } 06994 AST_LIST_TRAVERSE_SAFE_END 06995 06996 if (!cur_pkt_buf) 06997 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 06998 06999 ast_mutex_unlock(&to_here->lock); 07000 }
static void delete_users | ( | void | ) | [static] |
Definition at line 9899 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::entry, iax2_registry::expire, free, iax2_destroy(), iaxs, iaxsl, peer_delme_cb(), chan_iax2_pvt::reg, sched, and user_delme_cb().
09900 { 09901 struct iax2_registry *reg; 09902 09903 ao2_callback(users, 0, user_delme_cb, NULL); 09904 09905 AST_LIST_LOCK(®istrations); 09906 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 09907 ast_sched_del(sched, reg->expire); 09908 if (reg->callno) { 09909 int callno = reg->callno; 09910 ast_mutex_lock(&iaxsl[callno]); 09911 if (iaxs[callno]) { 09912 iaxs[callno]->reg = NULL; 09913 iax2_destroy(callno); 09914 } 09915 ast_mutex_unlock(&iaxsl[callno]); 09916 } 09917 if (reg->dnsmgr) 09918 ast_dnsmgr_release(reg->dnsmgr); 09919 free(reg); 09920 } 09921 AST_LIST_UNLOCK(®istrations); 09922 09923 ao2_callback(peers, 0, peer_delme_cb, NULL); 09924 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 1807 of file chan_iax2.c.
References ast_iax2_firmware_header::datalen, iax_firmware::fd, free, and iax_firmware::fwh.
Referenced by reload_firmware().
01808 { 01809 /* Close firmware */ 01810 if (cur->fwh) { 01811 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 01812 } 01813 close(cur->fd); 01814 free(cur); 01815 }
static void dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 6746 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().
06747 { 06748 unsigned short dpstatus = 0; 06749 struct iax_ie_data ied1; 06750 int mm; 06751 06752 memset(&ied1, 0, sizeof(ied1)); 06753 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 06754 /* Must be started */ 06755 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 06756 dpstatus = IAX_DPSTATUS_EXISTS; 06757 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 06758 dpstatus = IAX_DPSTATUS_CANEXIST; 06759 } else { 06760 dpstatus = IAX_DPSTATUS_NONEXISTENT; 06761 } 06762 if (ast_ignore_pattern(context, callednum)) 06763 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 06764 if (mm) 06765 dpstatus |= IAX_DPSTATUS_MATCHMORE; 06766 if (!skiplock) 06767 ast_mutex_lock(&iaxsl[callno]); 06768 if (iaxs[callno]) { 06769 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 06770 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 06771 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 06772 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 06773 } 06774 if (!skiplock) 06775 ast_mutex_unlock(&iaxsl[callno]); 06776 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 6778 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().
06779 { 06780 /* Look up for dpreq */ 06781 struct dpreq_data *dpr = data; 06782 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 06783 if (dpr->callerid) 06784 free(dpr->callerid); 06785 free(dpr); 06786 return NULL; 06787 }
static int encrypt_frame | ( | aes_encrypt_ctx * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 4319 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().
04320 { 04321 int padding; 04322 unsigned char *workspace; 04323 workspace = alloca(*datalen + 32); 04324 if (!workspace) 04325 return -1; 04326 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 04327 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 04328 if (option_debug && iaxdebug) 04329 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 04330 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 04331 padding = 16 + (padding & 0xf); 04332 memcpy(workspace, poo, padding); 04333 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 04334 workspace[15] &= 0xf0; 04335 workspace[15] |= (padding & 0xf); 04336 if (option_debug && iaxdebug) 04337 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]); 04338 *datalen += padding; 04339 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 04340 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 04341 memcpy(poo, workspace + *datalen - 32, 32); 04342 } else { 04343 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 04344 if (option_debug && iaxdebug) 04345 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen); 04346 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 04347 padding = 16 + (padding & 0xf); 04348 memcpy(workspace, poo, padding); 04349 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04350 workspace[15] &= 0xf0; 04351 workspace[15] |= (padding & 0x0f); 04352 *datalen += padding; 04353 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 04354 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 04355 memcpy(poo, workspace + *datalen - 32, 32); 04356 } 04357 return 0; 04358 }
static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 6189 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by iax2_prune_realtime(), reg_source_db(), and update_registry().
06190 { 06191 #ifdef SCHED_MULTITHREADED 06192 if (schedule_action(__expire_registry, data)) 06193 #endif 06194 __expire_registry(data); 06195 return 0; 06196 }
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 10458 of file chan_iax2.c.
References ARRAY_LEN, ast_calloc, ast_channel_defer_dtmf(), ast_channel_undefer_dtmf(), ast_copy_string(), ast_frfree, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_read(), ast_test_flag, ast_tvcmp(), ast_waitfor_nandfds(), CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, cache_get_callno_locked(), iax2_dpcache::callno, dpcache, dpcache_lock, chan_iax2_pvt::dpentries, errno, iax2_dpcache::expiry, iax2_dpcache::exten, f, iax2_dpcache::flags, free, iax2_dprequest(), IAX_STATE_STARTED, iaxs, iaxsl, LOG_WARNING, iax2_dpcache::next, iax2_dpcache::orig, iax2_dpcache::peer, iax2_dpcache::peercontext, and iax2_dpcache::waiters.
Referenced by iax2_canmatch(), iax2_exec(), iax2_exists(), and iax2_matchmore().
10459 { 10460 struct iax2_dpcache *dp, *prev = NULL, *next; 10461 struct timeval tv; 10462 int x; 10463 int com[2]; 10464 int timeout; 10465 int old=0; 10466 int outfd; 10467 int abort; 10468 int callno; 10469 struct ast_channel *c; 10470 struct ast_frame *f; 10471 gettimeofday(&tv, NULL); 10472 dp = dpcache; 10473 while(dp) { 10474 next = dp->next; 10475 /* Expire old caches */ 10476 if (ast_tvcmp(tv, dp->expiry) > 0) { 10477 /* It's expired, let it disappear */ 10478 if (prev) 10479 prev->next = dp->next; 10480 else 10481 dpcache = dp->next; 10482 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) { 10483 /* Free memory and go again */ 10484 free(dp); 10485 } else { 10486 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); 10487 } 10488 dp = next; 10489 continue; 10490 } 10491 /* We found an entry that matches us! */ 10492 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 10493 break; 10494 prev = dp; 10495 dp = next; 10496 } 10497 if (!dp) { 10498 /* No matching entry. Create a new one. */ 10499 /* First, can we make a callno? */ 10500 callno = cache_get_callno_locked(data); 10501 if (callno < 0) { 10502 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 10503 return NULL; 10504 } 10505 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 10506 ast_mutex_unlock(&iaxsl[callno]); 10507 return NULL; 10508 } 10509 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 10510 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 10511 gettimeofday(&dp->expiry, NULL); 10512 dp->orig = dp->expiry; 10513 /* Expires in 30 mins by default */ 10514 dp->expiry.tv_sec += iaxdefaultdpcache; 10515 dp->next = dpcache; 10516 dp->flags = CACHE_FLAG_PENDING; 10517 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 10518 dp->waiters[x] = -1; 10519 dpcache = dp; 10520 dp->peer = iaxs[callno]->dpentries; 10521 iaxs[callno]->dpentries = dp; 10522 /* Send the request if we're already up */ 10523 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 10524 iax2_dprequest(dp, callno); 10525 ast_mutex_unlock(&iaxsl[callno]); 10526 } 10527 /* By here we must have a dp */ 10528 if (dp->flags & CACHE_FLAG_PENDING) { 10529 /* Okay, here it starts to get nasty. We need a pipe now to wait 10530 for a reply to come back so long as it's pending */ 10531 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) { 10532 /* Find an empty slot */ 10533 if (dp->waiters[x] < 0) 10534 break; 10535 } 10536 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) { 10537 ast_log(LOG_WARNING, "No more waiter positions available\n"); 10538 return NULL; 10539 } 10540 if (pipe(com)) { 10541 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 10542 return NULL; 10543 } 10544 dp->waiters[x] = com[1]; 10545 /* Okay, now we wait */ 10546 timeout = iaxdefaulttimeout * 1000; 10547 /* Temporarily unlock */ 10548 ast_mutex_unlock(&dpcache_lock); 10549 /* Defer any dtmf */ 10550 if (chan) 10551 old = ast_channel_defer_dtmf(chan); 10552 abort = 0; 10553 while(timeout) { 10554 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 10555 if (outfd > -1) { 10556 break; 10557 } 10558 if (c) { 10559 f = ast_read(c); 10560 if (f) 10561 ast_frfree(f); 10562 else { 10563 /* Got hung up on, abort! */ 10564 break; 10565 abort = 1; 10566 } 10567 } 10568 } 10569 if (!timeout) { 10570 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 10571 } 10572 ast_mutex_lock(&dpcache_lock); 10573 dp->waiters[x] = -1; 10574 close(com[1]); 10575 close(com[0]); 10576 if (abort) { 10577 /* Don't interpret anything, just abort. Not sure what th epoint 10578 of undeferring dtmf on a hung up channel is but hey whatever */ 10579 if (!old && chan) 10580 ast_channel_undefer_dtmf(chan); 10581 return NULL; 10582 } 10583 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 10584 /* Now to do non-independent analysis the results of our wait */ 10585 if (dp->flags & CACHE_FLAG_PENDING) { 10586 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 10587 pending. Don't let it take as long to timeout. */ 10588 dp->flags &= ~CACHE_FLAG_PENDING; 10589 dp->flags |= CACHE_FLAG_TIMEOUT; 10590 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 10591 systems without leaving it unavailable once the server comes back online */ 10592 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 10593 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 10594 if (dp->waiters[x] > -1) { 10595 if (write(dp->waiters[x], "asdf", 4) < 0) { 10596 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 10597 } 10598 } 10599 } 10600 } 10601 } 10602 /* Our caller will obtain the rest */ 10603 if (!old && chan) 10604 ast_channel_undefer_dtmf(chan); 10605 } 10606 return dp; 10607 }
static int find_callno | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | sockfd, | |||
int | full_frame | |||
) | [static] |
Definition at line 1707 of file chan_iax2.c.
References __find_callno().
Referenced by iax2_poke_peer(), and socket_process().
01707 { 01708 01709 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame); 01710 }
static int find_callno_locked | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | sockfd, | |||
int | full_frame | |||
) | [static] |
Definition at line 1712 of file chan_iax2.c.
References __find_callno().
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_provision(), iax2_request(), and socket_process().
01712 { 01713 01714 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame); 01715 }
static struct iax2_thread* find_idle_thread | ( | void | ) | [static] |
Definition at line 908 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, iaxdynamicthreadnum, iaxmaxthreadcount, iax2_thread::list, and thread.
Referenced by __schedule_action(), and socket_read().
00909 { 00910 pthread_attr_t attr; 00911 struct iax2_thread *thread = NULL; 00912 00913 /* Pop the head of the list off */ 00914 AST_LIST_LOCK(&idle_list); 00915 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 00916 AST_LIST_UNLOCK(&idle_list); 00917 00918 /* If no idle thread is available from the regular list, try dynamic */ 00919 if (thread == NULL) { 00920 AST_LIST_LOCK(&dynamic_list); 00921 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 00922 /* Make sure we absolutely have a thread... if not, try to make one if allowed */ 00923 if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) { 00924 /* We need to MAKE a thread! */ 00925 if ((thread = ast_calloc(1, sizeof(*thread)))) { 00926 thread->threadnum = iaxdynamicthreadnum++; 00927 thread->type = IAX_TYPE_DYNAMIC; 00928 ast_mutex_init(&thread->lock); 00929 ast_cond_init(&thread->cond, NULL); 00930 pthread_attr_init(&attr); 00931 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 00932 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 00933 free(thread); 00934 thread = NULL; 00935 } else { 00936 /* All went well and the thread is up, so increment our count */ 00937 iaxdynamicthreadcount++; 00938 00939 /* Wait for the thread to be ready before returning it to the caller */ 00940 while (!thread->ready_for_signal) 00941 usleep(1); 00942 } 00943 } 00944 } 00945 AST_LIST_UNLOCK(&dynamic_list); 00946 } 00947 00948 /* this thread is not processing a full frame (since it is idle), 00949 so ensure that the field for the full frame call number is empty */ 00950 if (thread) 00951 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 00952 00953 return thread; 00954 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static] |
Definition at line 1151 of file chan_iax2.c.
References ao2_find(), iax2_peer::name, and realtime_peer().
01152 { 01153 struct iax2_peer *peer = NULL; 01154 struct iax2_peer tmp_peer = { 01155 .name = name, 01156 }; 01157 01158 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01159 01160 /* Now go for realtime if applicable */ 01161 if(!peer && realtime) 01162 peer = realtime_peer(name, NULL); 01163 01164 return peer; 01165 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static] |
Definition at line 4128 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_mutex_lock(), inaddrcmp(), iax2_trunk_peer::lock, iax2_trunk_peer::next, tpeerlock, and tpeers.
Referenced by iax2_trunk_queue(), and socket_process().
04129 { 04130 struct iax2_trunk_peer *tpeer; 04131 04132 /* Finds and locks trunk peer */ 04133 ast_mutex_lock(&tpeerlock); 04134 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) { 04135 /* We don't lock here because tpeer->addr *never* changes */ 04136 if (!inaddrcmp(&tpeer->addr, sin)) { 04137 ast_mutex_lock(&tpeer->lock); 04138 break; 04139 } 04140 } 04141 if (!tpeer) { 04142 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 04143 ast_mutex_init(&tpeer->lock); 04144 tpeer->lastsent = 9999; 04145 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 04146 tpeer->trunkact = ast_tvnow(); 04147 ast_mutex_lock(&tpeer->lock); 04148 tpeer->next = tpeers; 04149 tpeer->sockfd = fd; 04150 tpeers = tpeer; 04151 #ifdef SO_NO_CHECK 04152 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 04153 #endif 04154 if (option_debug) 04155 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 04156 } 04157 } 04158 ast_mutex_unlock(&tpeerlock); 04159 return tpeer; 04160 }
static unsigned int fix_peerts | ( | struct timeval * | tv, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 3944 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvzero(), iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process().
03945 { 03946 long ms; /* NOT unsigned */ 03947 if (ast_tvzero(iaxs[callno]->rxcore)) { 03948 /* Initialize rxcore time if appropriate */ 03949 gettimeofday(&iaxs[callno]->rxcore, NULL); 03950 /* Round to nearest 20ms so traces look pretty */ 03951 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 03952 } 03953 /* Calculate difference between trunk and channel */ 03954 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore); 03955 /* Return as the sum of trunk time and the difference between trunk and real time */ 03956 return ms + ts; 03957 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 9075 of file chan_iax2.c.
References free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
09076 { 09077 struct iax2_context *conl; 09078 while(con) { 09079 conl = con; 09080 con = con->next; 09081 free(conl); 09082 } 09083 }
static int function_iaxpeer | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 10731 of file chan_iax2.c.
References iax2_peer::addr, ast_codec_pref_index(), ast_copy_string(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strdupa, ast_test_flag, iax2_peer::callno, iax2_peer::capability, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::expire, find_peer(), iax2_tech, IAX_DYNAMIC, iaxs, iax2_peer::mailbox, peer_status(), peer_unref(), iax2_peer::prefs, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.
10732 { 10733 struct iax2_peer *peer; 10734 char *peername, *colname; 10735 10736 peername = ast_strdupa(data); 10737 10738 /* if our channel, return the IP address of the endpoint of current channel */ 10739 if (!strcmp(peername,"CURRENTCHANNEL")) { 10740 unsigned short callno; 10741 if (chan->tech != &iax2_tech) 10742 return -1; 10743 callno = PTR_TO_CALLNO(chan->tech_pvt); 10744 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 10745 return 0; 10746 } 10747 10748 if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */ 10749 *colname++ = '\0'; 10750 else if ((colname = strchr(peername, '|'))) 10751 *colname++ = '\0'; 10752 else 10753 colname = "ip"; 10754 10755 if (!(peer = find_peer(peername, 1))) 10756 return -1; 10757 10758 if (!strcasecmp(colname, "ip")) { 10759 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 10760 } else if (!strcasecmp(colname, "status")) { 10761 peer_status(peer, buf, len); 10762 } else if (!strcasecmp(colname, "mailbox")) { 10763 ast_copy_string(buf, peer->mailbox, len); 10764 } else if (!strcasecmp(colname, "context")) { 10765 ast_copy_string(buf, peer->context, len); 10766 } else if (!strcasecmp(colname, "expire")) { 10767 snprintf(buf, len, "%d", peer->expire); 10768 } else if (!strcasecmp(colname, "dynamic")) { 10769 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 10770 } else if (!strcasecmp(colname, "callerid_name")) { 10771 ast_copy_string(buf, peer->cid_name, len); 10772 } else if (!strcasecmp(colname, "callerid_num")) { 10773 ast_copy_string(buf, peer->cid_num, len); 10774 } else if (!strcasecmp(colname, "codecs")) { 10775 ast_getformatname_multiple(buf, len -1, peer->capability); 10776 } else if (!strncasecmp(colname, "codec[", 6)) { 10777 char *codecnum, *ptr; 10778 int index = 0, codec = 0; 10779 10780 codecnum = strchr(colname, '['); 10781 *codecnum = '\0'; 10782 codecnum++; 10783 if ((ptr = strchr(codecnum, ']'))) { 10784 *ptr = '\0'; 10785 } 10786 index = atoi(codecnum); 10787 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 10788 ast_copy_string(buf, ast_getformatname(codec), len); 10789 } else { 10790 buf[0] = '\0'; 10791 } 10792 } else { 10793 buf[0] = '\0'; 10794 } 10795 10796 peer_unref(peer); 10797 10798 return 0; 10799 }
static int get_auth_methods | ( | char * | value | ) | [static] |
Definition at line 9299 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
09300 { 09301 int methods = 0; 09302 if (strstr(value, "rsa")) 09303 methods |= IAX_AUTH_RSA; 09304 if (strstr(value, "md5")) 09305 methods |= IAX_AUTH_MD5; 09306 if (strstr(value, "plaintext")) 09307 methods |= IAX_AUTH_PLAINTEXT; 09308 return methods; 09309 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1028 of file chan_iax2.c.
References ast_true(), and IAX_ENCRYPT_AES128.
Referenced by build_peer(), build_user(), and set_config().
01029 { 01030 int e; 01031 if (!strcasecmp(s, "aes128")) 01032 e = IAX_ENCRYPT_AES128; 01033 else if (ast_true(s)) 01034 e = IAX_ENCRYPT_AES128; 01035 else 01036 e = 0; 01037 return e; 01038 }
static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 2693 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
02694 { 02695 #ifdef SCHED_MULTITHREADED 02696 if (schedule_action(__get_from_jb, data)) 02697 #endif 02698 __get_from_jb(data); 02699 return 0; 02700 }
static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 6944 of file chan_iax2.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), iax2_pkt_buf::buf, iax2_pkt_buf::entry, iax2_pkt_buf::len, socket_process(), and thread.
06945 { 06946 struct iax2_pkt_buf *pkt_buf; 06947 06948 ast_mutex_lock(&thread->lock); 06949 06950 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 06951 ast_mutex_unlock(&thread->lock); 06952 06953 thread->buf = pkt_buf->buf; 06954 thread->buf_len = pkt_buf->len; 06955 thread->buf_size = pkt_buf->len + 1; 06956 06957 socket_process(thread); 06958 06959 thread->buf = NULL; 06960 ast_free(pkt_buf); 06961 06962 ast_mutex_lock(&thread->lock); 06963 } 06964 06965 ast_mutex_unlock(&thread->lock); 06966 }
static int handle_error | ( | void | ) | [static] |
Definition at line 2095 of file chan_iax2.c.
References ast_inet_ntoa(), ast_log(), errno, LOG_WARNING, and netsocket.
Referenced by send_packet(), socket_read(), and transmit_trunk().
02096 { 02097 /* XXX Ideally we should figure out why an error occured and then abort those 02098 rather than continuing to try. Unfortunately, the published interface does 02099 not seem to work XXX */ 02100 #if 0 02101 struct sockaddr_in *sin; 02102 int res; 02103 struct msghdr m; 02104 struct sock_extended_err e; 02105 m.msg_name = NULL; 02106 m.msg_namelen = 0; 02107 m.msg_iov = NULL; 02108 m.msg_control = &e; 02109 m.msg_controllen = sizeof(e); 02110 m.msg_flags = 0; 02111 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 02112 if (res < 0) 02113 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 02114 else { 02115 if (m.msg_controllen) { 02116 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 02117 if (sin) 02118 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 02119 else 02120 ast_log(LOG_WARNING, "No address detected??\n"); 02121 } else { 02122 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 02123 } 02124 } 02125 #endif 02126 return 0; 02127 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 6010 of file chan_iax2.c.
References iax2_registry::addr, ast_copy_string(), ast_inet_ntoa(), ast_log(), AST_SCHED_DEL, ast_verbose(), EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), iax2_sched_add(), iaxs, ies, inaddrcmp(), LOG_WARNING, manager_event(), iax2_registry::messages, option_verbose, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGISTERED, iax2_registry::regstate, sched, iax2_registry::us, and VERBOSE_PREFIX_3.
Referenced by socket_process().
06011 { 06012 struct iax2_registry *reg; 06013 /* Start pessimistic */ 06014 char peer[256] = ""; 06015 char msgstatus[60]; 06016 int refresh = 60; 06017 char ourip[256] = "<Unspecified>"; 06018 struct sockaddr_in oldus; 06019 struct sockaddr_in us; 06020 int oldmsgs; 06021 06022 memset(&us, 0, sizeof(us)); 06023 if (ies->apparent_addr) 06024 bcopy(ies->apparent_addr, &us, sizeof(us)); 06025 if (ies->username) 06026 ast_copy_string(peer, ies->username, sizeof(peer)); 06027 if (ies->refresh) 06028 refresh = ies->refresh; 06029 if (ies->calling_number) { 06030 /* We don't do anything with it really, but maybe we should */ 06031 } 06032 reg = iaxs[callno]->reg; 06033 if (!reg) { 06034 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 06035 return -1; 06036 } 06037 memcpy(&oldus, ®->us, sizeof(oldus)); 06038 oldmsgs = reg->messages; 06039 if (inaddrcmp(®->addr, sin)) { 06040 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 06041 return -1; 06042 } 06043 memcpy(®->us, &us, sizeof(reg->us)); 06044 if (ies->msgcount >= 0) 06045 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 06046 /* always refresh the registration at the interval requested by the server 06047 we are registering to 06048 */ 06049 reg->refresh = refresh; 06050 AST_SCHED_DEL(sched, reg->expire); 06051 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 06052 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 06053 if (option_verbose > 2) { 06054 if (reg->messages > 255) 06055 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 06056 else if (reg->messages > 1) 06057 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages); 06058 else if (reg->messages > 0) 06059 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n"); 06060 else 06061 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n"); 06062 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 06063 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 06064 } 06065 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 06066 } 06067 reg->regstate = REG_STATE_REGISTERED; 06068 return 0; 06069 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3750 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.
03751 { 03752 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03753 if (option_debug) 03754 ast_log(LOG_DEBUG, "Answering IAX2 call\n"); 03755 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 03756 }
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 3596 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.
03597 { 03598 struct ast_channel *cs[3]; 03599 struct ast_channel *who, *other; 03600 int to = -1; 03601 int res = -1; 03602 int transferstarted=0; 03603 struct ast_frame *f; 03604 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 03605 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 03606 struct timeval waittimer = {0, 0}, tv; 03607 03608 lock_both(callno0, callno1); 03609 if (!iaxs[callno0] || !iaxs[callno1]) { 03610 unlock_both(callno0, callno1); 03611 return AST_BRIDGE_FAILED; 03612 } 03613 /* Put them in native bridge mode */ 03614 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) { 03615 iaxs[callno0]->bridgecallno = callno1; 03616 iaxs[callno1]->bridgecallno = callno0; 03617 } 03618 /* If the bridge got retried, don't queue up more packets - the transfer request will be retransmitted as necessary */ 03619 if (iaxs[callno0]->transferring && iaxs[callno1]->transferring) { 03620 transferstarted = 1; 03621 } 03622 unlock_both(callno0, callno1); 03623 03624 /* If not, try to bridge until we can execute a transfer, if we can */ 03625 cs[0] = c0; 03626 cs[1] = c1; 03627 for (/* ever */;;) { 03628 /* Check in case we got masqueraded into */ 03629 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 03630 if (option_verbose > 2) 03631 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n"); 03632 /* Remove from native mode */ 03633 if (c0->tech == &iax2_tech) { 03634 ast_mutex_lock(&iaxsl[callno0]); 03635 iaxs[callno0]->bridgecallno = 0; 03636 ast_mutex_unlock(&iaxsl[callno0]); 03637 } 03638 if (c1->tech == &iax2_tech) { 03639 ast_mutex_lock(&iaxsl[callno1]); 03640 iaxs[callno1]->bridgecallno = 0; 03641 ast_mutex_unlock(&iaxsl[callno1]); 03642 } 03643 return AST_BRIDGE_FAILED_NOWARN; 03644 } 03645 if (c0->nativeformats != c1->nativeformats) { 03646 if (option_verbose > 2) { 03647 char buf0[255]; 03648 char buf1[255]; 03649 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 03650 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 03651 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 03652 } 03653 /* Remove from native mode */ 03654 lock_both(callno0, callno1); 03655 if (iaxs[callno0]) 03656 iaxs[callno0]->bridgecallno = 0; 03657 if (iaxs[callno1]) 03658 iaxs[callno1]->bridgecallno = 0; 03659 unlock_both(callno0, callno1); 03660 return AST_BRIDGE_FAILED_NOWARN; 03661 } 03662 /* check if transfered and if we really want native bridging */ 03663 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) { 03664 /* Try the transfer */ 03665 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 03666 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA))) 03667 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 03668 transferstarted = 1; 03669 } 03670 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 03671 /* Call has been transferred. We're no longer involved */ 03672 gettimeofday(&tv, NULL); 03673 if (ast_tvzero(waittimer)) { 03674 waittimer = tv; 03675 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 03676 c0->_softhangup |= AST_SOFTHANGUP_DEV; 03677 c1->_softhangup |= AST_SOFTHANGUP_DEV; 03678 *fo = NULL; 03679 *rc = c0; 03680 res = AST_BRIDGE_COMPLETE; 03681 break; 03682 } 03683 } 03684 to = 1000; 03685 who = ast_waitfor_n(cs, 2, &to); 03686 if (timeoutms > -1) { 03687 timeoutms -= (1000 - to); 03688 if (timeoutms < 0) 03689 timeoutms = 0; 03690 } 03691 if (!who) { 03692 if (!timeoutms) { 03693 res = AST_BRIDGE_RETRY; 03694 break; 03695 } 03696 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 03697 res = AST_BRIDGE_FAILED; 03698 break; 03699 } 03700 continue; 03701 } 03702 f = ast_read(who); 03703 if (!f) { 03704 *fo = NULL; 03705 *rc = who; 03706 res = AST_BRIDGE_COMPLETE; 03707 break; 03708 } 03709 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 03710 *fo = f; 03711 *rc = who; 03712 res = AST_BRIDGE_COMPLETE; 03713 break; 03714 } 03715 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 03716 if ((f->frametype == AST_FRAME_VOICE) || 03717 (f->frametype == AST_FRAME_TEXT) || 03718 (f->frametype == AST_FRAME_VIDEO) || 03719 (f->frametype == AST_FRAME_IMAGE) || 03720 (f->frametype == AST_FRAME_DTMF)) { 03721 /* monitored dtmf take out of the bridge. 03722 * check if we monitor the specific source. 03723 */ 03724 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 03725 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 03726 *rc = who; 03727 *fo = f; 03728 res = AST_BRIDGE_COMPLETE; 03729 /* Remove from native mode */ 03730 break; 03731 } 03732 /* everything else goes to the other side */ 03733 ast_write(other, f); 03734 } 03735 ast_frfree(f); 03736 /* Swap who gets priority */ 03737 cs[2] = cs[0]; 03738 cs[0] = cs[1]; 03739 cs[1] = cs[2]; 03740 } 03741 lock_both(callno0, callno1); 03742 if(iaxs[callno0]) 03743 iaxs[callno0]->bridgecallno = 0; 03744 if(iaxs[callno1]) 03745 iaxs[callno1]->bridgecallno = 0; 03746 unlock_both(callno0, callno1); 03747 return res; 03748 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 3293 of file chan_iax2.c.
References ast_channel::_state, chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_copy_string(), AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PRES_NUMBER_NOT_AVAILABLE, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, auto_congest(), CALLNO_TO_PTR, capability, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, create_addr(), chan_iax2_pvt::encmethods, iax2_datetime(), iax2_sched_add(), IAX_COMMAND_NEW, IAX_IE_ADSICPE, iax_ie_append(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTOANSWER, IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CALLING_ANI, IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_CALLINGPRES, IAX_IE_CALLINGTNS, IAX_IE_CALLINGTON, IAX_IE_CAPABILITY, IAX_IE_CODEC_PREFS, IAX_IE_DATETIME, IAX_IE_DNID, IAX_IE_ENCRYPTION, IAX_IE_FORMAT, IAX_IE_LANGUAGE, IAX_IE_RDNIS, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, IAX_SENDANI, iaxs, iaxsl, chan_iax2_pvt::initid, ast_channel::language, LOG_WARNING, chan_iax2_pvt::maxtime, create_addr_info::maxtime, chan_iax2_pvt::mohinterpret, chan_iax2_pvt::mohsuggest, ast_channel::name, 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, ast_channel::tech_pvt, and chan_iax2_pvt::username.
03294 { 03295 struct sockaddr_in sin; 03296 char *l=NULL, *n=NULL, *tmpstr; 03297 struct iax_ie_data ied; 03298 char *defaultrdest = "s"; 03299 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03300 struct parsed_dial_string pds; 03301 struct create_addr_info cai; 03302 03303 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 03304 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 03305 return -1; 03306 } 03307 03308 memset(&cai, 0, sizeof(cai)); 03309 cai.encmethods = iax2_encryption; 03310 03311 memset(&pds, 0, sizeof(pds)); 03312 tmpstr = ast_strdupa(dest); 03313 parse_dial_string(tmpstr, &pds); 03314 03315 if (ast_strlen_zero(pds.peer)) { 03316 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 03317 return -1; 03318 } 03319 03320 if (!pds.exten) { 03321 pds.exten = defaultrdest; 03322 } 03323 03324 if (create_addr(pds.peer, c, &sin, &cai)) { 03325 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 03326 return -1; 03327 } 03328 03329 if (!pds.username && !ast_strlen_zero(cai.username)) 03330 pds.username = cai.username; 03331 if (!pds.password && !ast_strlen_zero(cai.secret)) 03332 pds.password = cai.secret; 03333 if (!pds.key && !ast_strlen_zero(cai.outkey)) 03334 pds.key = cai.outkey; 03335 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 03336 pds.context = cai.peercontext; 03337 03338 /* Keep track of the context for outgoing calls too */ 03339 ast_copy_string(c->context, cai.context, sizeof(c->context)); 03340 03341 if (pds.port) 03342 sin.sin_port = htons(atoi(pds.port)); 03343 03344 l = c->cid.cid_num; 03345 n = c->cid.cid_name; 03346 03347 /* Now build request */ 03348 memset(&ied, 0, sizeof(ied)); 03349 03350 /* On new call, first IE MUST be IAX version of caller */ 03351 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 03352 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 03353 if (pds.options && strchr(pds.options, 'a')) { 03354 /* Request auto answer */ 03355 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 03356 } 03357 03358 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 03359 03360 if (l) { 03361 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 03362 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03363 } else { 03364 if (n) 03365 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03366 else 03367 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 03368 } 03369 03370 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton); 03371 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns); 03372 03373 if (n) 03374 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 03375 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani) 03376 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani); 03377 03378 if (!ast_strlen_zero(c->language)) 03379 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 03380 if (!ast_strlen_zero(c->cid.cid_dnid)) 03381 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid); 03382 if (!ast_strlen_zero(c->cid.cid_rdnis)) 03383 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis); 03384 03385 if (pds.context) 03386 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 03387 03388 if (pds.username) 03389 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 03390 03391 if (cai.encmethods) 03392 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 03393 03394 ast_mutex_lock(&iaxsl[callno]); 03395 03396 if (!ast_strlen_zero(c->context)) 03397 ast_string_field_set(iaxs[callno], context, c->context); 03398 03399 if (pds.username) 03400 ast_string_field_set(iaxs[callno], username, pds.username); 03401 03402 iaxs[callno]->encmethods = cai.encmethods; 03403 03404 iaxs[callno]->adsi = cai.adsi; 03405 03406 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 03407 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 03408 03409 if (pds.key) 03410 ast_string_field_set(iaxs[callno], outkey, pds.key); 03411 if (pds.password) 03412 ast_string_field_set(iaxs[callno], secret, pds.password); 03413 03414 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); 03415 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); 03416 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 03417 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 03418 03419 if (iaxs[callno]->maxtime) { 03420 /* Initialize pingtime and auto-congest time */ 03421 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 03422 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 03423 } else if (autokill) { 03424 iaxs[callno]->pingtime = autokill / 2; 03425 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 03426 } 03427 03428 /* send the command using the appropriate socket for this peer */ 03429 iaxs[callno]->sockfd = cai.sockfd; 03430 03431 /* Transmit the string in a "NEW" request */ 03432 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 03433 03434 ast_mutex_unlock(&iaxsl[callno]); 03435 ast_setstate(c, AST_STATE_RINGING); 03436 03437 return 0; 03438 }
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 10633 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_CANEXIST, dpcache_lock, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
10634 { 10635 int res = 0; 10636 struct iax2_dpcache *dp; 10637 #if 0 10638 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10639 #endif 10640 if ((priority != 1) && (priority != 2)) 10641 return 0; 10642 ast_mutex_lock(&dpcache_lock); 10643 dp = find_cache(chan, data, context, exten, priority); 10644 if (dp) { 10645 if (dp->flags & CACHE_FLAG_CANEXIST) 10646 res= 1; 10647 } 10648 ast_mutex_unlock(&dpcache_lock); 10649 if (!dp) { 10650 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10651 } 10652 return res; 10653 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 3196 of file chan_iax2.c.
References ast_localtime(), ast_strlen_zero(), and t.
Referenced by iax2_call(), and update_registry().
03197 { 03198 time_t t; 03199 struct tm tm; 03200 unsigned int tmp; 03201 time(&t); 03202 if (!ast_strlen_zero(tz)) 03203 ast_localtime(&t, &tm, tz); 03204 else 03205 ast_localtime(&t, &tm, NULL); 03206 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 03207 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 03208 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 03209 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 03210 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 03211 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 03212 return tmp; 03213 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 1291 of file chan_iax2.c.
References ao2_ref(), ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), AST_SCHED_DEL_SPINLOCK, DEADLOCK_AVOIDANCE, ast_channel::lock, LOG_DEBUG, option_debug, chan_iax2_pvt::owner, chan_iax2_pvt::peercallno, remove_by_peercallno(), sched, and update_max_trunk().
Referenced by __attempt_transmit(), __iax2_poke_noanswer(), __unload_module(), delete_users(), iax2_do_register(), iax2_hangup(), iax2_poke_peer(), peer_destructor(), scheduled_destroy(), and socket_process().
01292 { 01293 struct chan_iax2_pvt *pvt; 01294 struct ast_channel *owner; 01295 01296 retry: 01297 pvt = iaxs[callno]; 01298 gettimeofday(&lastused[callno], NULL); 01299 01300 owner = pvt ? pvt->owner : NULL; 01301 01302 if (owner) { 01303 if (ast_mutex_trylock(&owner->lock)) { 01304 if (option_debug > 2) 01305 ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n"); 01306 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01307 goto retry; 01308 } 01309 } 01310 if (!owner && iaxs[callno]) { 01311 AST_SCHED_DEL_SPINLOCK(sched, iaxs[callno]->lagid, &iaxsl[callno]); 01312 AST_SCHED_DEL_SPINLOCK(sched, iaxs[callno]->pingid, &iaxsl[callno]); 01313 iaxs[callno] = NULL; 01314 } 01315 01316 if (pvt) { 01317 if (!owner) { 01318 pvt->owner = NULL; 01319 } else { 01320 /* If there's an owner, prod it to give up */ 01321 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 01322 * because we already hold the owner channel lock. */ 01323 ast_queue_hangup(owner); 01324 } 01325 01326 if (pvt->peercallno) { 01327 remove_by_peercallno(pvt); 01328 } 01329 01330 if (!owner) { 01331 ao2_ref(pvt, -1); 01332 pvt = NULL; 01333 } 01334 } 01335 01336 if (owner) { 01337 ast_mutex_unlock(&owner->lock); 01338 } 01339 01340 if (callno & 0x4000) { 01341 update_max_trunk(); 01342 } 01343 }
static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1221 of file chan_iax2.c.
References ao2_find(), ast_atomic_fetchadd_int(), 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, iax2_user::name, chan_iax2_pvt::pingid, sched, user_unref(), and chan_iax2_pvt::username.
Referenced by iax2_predestroy(), pvt_destructor(), and stop_stuff().
01222 { 01223 /* Decrement AUTHREQ count if needed */ 01224 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01225 struct iax2_user *user; 01226 struct iax2_user tmp_user = { 01227 .name = pvt->username, 01228 }; 01229 01230 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01231 if (user) { 01232 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01233 user = user_unref(user); 01234 } 01235 01236 ast_clear_flag(pvt, IAX_MAXAUTHREQ); 01237 } 01238 01239 /* No more pings or lagrq's */ 01240 AST_SCHED_DEL(sched, pvt->pingid); 01241 AST_SCHED_DEL(sched, pvt->lagid); 01242 AST_SCHED_DEL(sched, pvt->autoid); 01243 AST_SCHED_DEL(sched, pvt->authid); 01244 AST_SCHED_DEL(sched, pvt->initid); 01245 AST_SCHED_DEL(sched, pvt->jbid); 01246 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 10824 of file chan_iax2.c.
References iax2_peer::addr, AST_DEVICE_INVALID, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_log(), ast_strdupa, ast_strlen_zero(), iax2_peer::defaddr, find_peer(), iax2_peer::historicms, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, option_debug, parse_dial_string(), and peer_unref().
10825 { 10826 struct parsed_dial_string pds; 10827 char *tmp = ast_strdupa(data); 10828 struct iax2_peer *p; 10829 int res = AST_DEVICE_INVALID; 10830 10831 memset(&pds, 0, sizeof(pds)); 10832 parse_dial_string(tmp, &pds); 10833 10834 if (ast_strlen_zero(pds.peer)) { 10835 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 10836 return res; 10837 } 10838 10839 if (option_debug > 2) 10840 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer); 10841 10842 /* SLD: FIXME: second call to find_peer during registration */ 10843 if (!(p = find_peer(pds.peer, 1))) 10844 return res; 10845 10846 res = AST_DEVICE_UNAVAILABLE; 10847 if (option_debug > 2) 10848 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 10849 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 10850 10851 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 10852 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 10853 /* Peer is registered, or have default IP address 10854 and a valid registration */ 10855 if (p->historicms == 0 || p->historicms <= p->maxms) 10856 /* let the core figure out whether it is in use or not */ 10857 res = AST_DEVICE_UNKNOWN; 10858 } 10859 10860 peer_unref(p); 10861 10862 return res; 10863 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 2812 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02813 { 02814 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 02815 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 2817 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02818 { 02819 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 02820 }
static int iax2_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5050 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05051 { 05052 if (argc < 2 || argc > 3) 05053 return RESULT_SHOWUSAGE; 05054 iaxdebug = 1; 05055 ast_cli(fd, "IAX2 Debugging Enabled\n"); 05056 return RESULT_SUCCESS; 05057 }
static int iax2_do_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5068 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05069 { 05070 if (argc < 3 || argc > 4) 05071 return RESULT_SHOWUSAGE; 05072 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 05073 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 05074 return RESULT_SUCCESS; 05075 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 8793 of file chan_iax2.c.
References iax2_registry::addr, ast_dnsmgr_changed(), ast_dnsmgr_refresh(), AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_SCHED_DEL, iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, find_callno_locked(), iax2_destroy(), iax2_do_register_s(), iax2_sched_add(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, iaxsl, LOG_WARNING, NEW_FORCE, option_debug, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), and iax2_registry::username.
Referenced by __iax2_do_register_s(), load_module(), and reload_config().
08794 { 08795 struct iax_ie_data ied; 08796 if (option_debug && iaxdebug) 08797 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username); 08798 08799 if (reg->dnsmgr && 08800 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) { 08801 /* Maybe the IP has changed, force DNS refresh */ 08802 ast_dnsmgr_refresh(reg->dnsmgr); 08803 } 08804 08805 /* 08806 * if IP has Changed, free allocated call to create a new one with new IP 08807 * call has the pointer to IP and must be updated to the new one 08808 */ 08809 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 08810 int callno = reg->callno; 08811 ast_mutex_lock(&iaxsl[callno]); 08812 iax2_destroy(callno); 08813 ast_mutex_unlock(&iaxsl[callno]); 08814 reg->callno = 0; 08815 } 08816 if (!reg->addr.sin_addr.s_addr) { 08817 if (option_debug && iaxdebug) 08818 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username); 08819 /* Setup the next registration attempt */ 08820 AST_SCHED_DEL(sched, reg->expire); 08821 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08822 return -1; 08823 } 08824 08825 if (!reg->callno) { 08826 if (option_debug) 08827 ast_log(LOG_DEBUG, "Allocate call number\n"); 08828 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0); 08829 if (reg->callno < 1) { 08830 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 08831 return -1; 08832 } else if (option_debug) 08833 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno); 08834 iaxs[reg->callno]->reg = reg; 08835 ast_mutex_unlock(&iaxsl[reg->callno]); 08836 } 08837 /* Schedule the next registration attempt */ 08838 AST_SCHED_DEL(sched, reg->expire); 08839 /* Setup the next registration a little early */ 08840 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08841 /* Send the request */ 08842 memset(&ied, 0, sizeof(ied)); 08843 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 08844 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 08845 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 08846 reg->regstate = REG_STATE_REGSENT; 08847 return 0; 08848 }
static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 5854 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
05855 { 05856 #ifdef SCHED_MULTITHREADED 05857 if (schedule_action(__iax2_do_register_s, data)) 05858 #endif 05859 __iax2_do_register_s(data); 05860 return 0; 05861 }
static int iax2_do_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5059 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05060 { 05061 if (argc < 3 || argc > 4) 05062 return RESULT_SHOWUSAGE; 05063 iaxtrunkdebug = 1; 05064 ast_cli(fd, "IAX2 Trunk Debug Requested\n"); 05065 return RESULT_SUCCESS; 05066 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 6555 of file chan_iax2.c.
References AST_FRAME_IAX, AST_SCHED_DEL, auto_hangup(), chan_iax2_pvt::autoid, CACHE_FLAG_TRANSMITTED, iax2_dpcache::exten, iax2_dpcache::flags, iax2_sched_add(), IAX_COMMAND_DPREQ, iax_ie_append_str(), IAX_IE_CALLED_NUMBER, iaxs, sched, and send_command().
Referenced by find_cache(), and socket_process().
06556 { 06557 struct iax_ie_data ied; 06558 /* Auto-hangup with 30 seconds of inactivity */ 06559 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 06560 iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno); 06561 memset(&ied, 0, sizeof(ied)); 06562 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 06563 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 06564 dp->flags |= CACHE_FLAG_TRANSMITTED; 06565 }
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 10679 of file chan_iax2.c.
References ast_copy_string(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), CACHE_FLAG_EXISTS, dpcache_lock, find_cache(), iax2_dpcache::flags, LOG_NOTICE, LOG_WARNING, option_verbose, pbx_builtin_getvar_helper(), pbx_exec(), pbx_findapp(), and VERBOSE_PREFIX_3.
10680 { 10681 char odata[256]; 10682 char req[256]; 10683 char *ncontext; 10684 struct iax2_dpcache *dp; 10685 struct ast_app *dial; 10686 #if 0 10687 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); 10688 #endif 10689 if (priority == 2) { 10690 /* Indicate status, can be overridden in dialplan */ 10691 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 10692 if (dialstatus) { 10693 dial = pbx_findapp(dialstatus); 10694 if (dial) 10695 pbx_exec(chan, dial, ""); 10696 } 10697 return -1; 10698 } else if (priority != 1) 10699 return -1; 10700 ast_mutex_lock(&dpcache_lock); 10701 dp = find_cache(chan, data, context, exten, priority); 10702 if (dp) { 10703 if (dp->flags & CACHE_FLAG_EXISTS) { 10704 ast_copy_string(odata, data, sizeof(odata)); 10705 ncontext = strchr(odata, '/'); 10706 if (ncontext) { 10707 *ncontext = '\0'; 10708 ncontext++; 10709 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 10710 } else { 10711 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 10712 } 10713 if (option_verbose > 2) 10714 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req); 10715 } else { 10716 ast_mutex_unlock(&dpcache_lock); 10717 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 10718 return -1; 10719 } 10720 } 10721 ast_mutex_unlock(&dpcache_lock); 10722 dial = pbx_findapp("Dial"); 10723 if (dial) { 10724 return pbx_exec(chan, dial, req); 10725 } else { 10726 ast_log(LOG_WARNING, "No dial application registered\n"); 10727 } 10728 return -1; 10729 }
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 10610 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_EXISTS, dpcache_lock, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
10611 { 10612 struct iax2_dpcache *dp; 10613 int res = 0; 10614 #if 0 10615 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10616 #endif 10617 if ((priority != 1) && (priority != 2)) 10618 return 0; 10619 ast_mutex_lock(&dpcache_lock); 10620 dp = find_cache(chan, data, context, exten, priority); 10621 if (dp) { 10622 if (dp->flags & CACHE_FLAG_EXISTS) 10623 res= 1; 10624 } 10625 ast_mutex_unlock(&dpcache_lock); 10626 if (!dp) { 10627 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10628 } 10629 return res; 10630 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 2839 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iaxs, iaxsl, LOG_WARNING, chan_iax2_pvt::owner, PTR_TO_CALLNO, and ast_channel::tech_pvt.
02840 { 02841 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 02842 ast_mutex_lock(&iaxsl[callno]); 02843 if (iaxs[callno]) 02844 iaxs[callno]->owner = newchan; 02845 else 02846 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 02847 ast_mutex_unlock(&iaxsl[callno]); 02848 return 0; 02849 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1285 of file chan_iax2.c.
References AST_SCHED_DEL, iax_frame_free(), iax_frame::retrans, and sched.
Referenced by __attempt_transmit(), __do_deliver(), __get_from_jb(), complete_transfer(), pvt_destructor(), and schedule_delivery().
01286 { 01287 AST_SCHED_DEL(sched, fr->retrans); 01288 iax_frame_free(fr); 01289 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len | |||
) | [static] |
Definition at line 1191 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), ast_copy_string(), iax2_peer::name, peer_unref(), and realtime_peer().
Referenced by __find_callno().
01192 { 01193 struct iax2_peer *peer = NULL; 01194 int res = 0; 01195 struct ao2_iterator i; 01196 01197 i = ao2_iterator_init(peers, 0); 01198 while ((peer = ao2_iterator_next(&i))) { 01199 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01200 (peer->addr.sin_port == sin.sin_port)) { 01201 ast_copy_string(host, peer->name, len); 01202 peer_unref(peer); 01203 res = 1; 01204 break; 01205 } 01206 peer_unref(peer); 01207 } 01208 01209 if (!peer) { 01210 peer = realtime_peer(NULL, &sin); 01211 if (peer) { 01212 ast_copy_string(host, peer->name, len); 01213 peer_unref(peer); 01214 res = 1; 01215 } 01216 } 01217 01218 return res; 01219 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 3817 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), ast_test_flag, IAX_TRUNK, and peer_unref().
Referenced by check_access().
03818 { 03819 struct iax2_peer *peer; 03820 int res = 0; 03821 struct ao2_iterator i; 03822 03823 i = ao2_iterator_init(peers, 0); 03824 while ((peer = ao2_iterator_next(&i))) { 03825 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 03826 (peer->addr.sin_port == sin.sin_port)) { 03827 res = ast_test_flag(peer, IAX_TRUNK); 03828 peer_unref(peer); 03829 break; 03830 } 03831 peer_unref(peer); 03832 } 03833 03834 return res; 03835 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3440 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_test_flag, ast_verbose(), CALLNO_TO_PTR, ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, iaxs, iaxsl, LOG_WARNING, ast_channel::name, option_debug, option_verbose, PTR_TO_CALLNO, sched, scheduled_destroy(), send_command_final(), ast_channel::tech_pvt, and VERBOSE_PREFIX_3.
03441 { 03442 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03443 struct iax_ie_data ied; 03444 int alreadygone; 03445 memset(&ied, 0, sizeof(ied)); 03446 ast_mutex_lock(&iaxsl[callno]); 03447 if (callno && iaxs[callno]) { 03448 if (option_debug) 03449 ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name); 03450 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 03451 /* Send the hangup unless we have had a transmission error or are already gone */ 03452 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 03453 if (!iaxs[callno]->error && !alreadygone) { 03454 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) { 03455 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno); 03456 } 03457 if (!iaxs[callno]) { 03458 ast_mutex_unlock(&iaxsl[callno]); 03459 return 0; 03460 } 03461 } 03462 /* Explicitly predestroy it */ 03463 iax2_predestroy(callno); 03464 /* If we were already gone to begin with, destroy us now */ 03465 if (iaxs[callno] && alreadygone) { 03466 if (option_debug) 03467 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name); 03468 iax2_destroy(callno); 03469 } else if (iaxs[callno]) { 03470 ast_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)); 03471 } 03472 } else if (c->tech_pvt) { 03473 /* If this call no longer exists, but the channel still 03474 * references it we need to set the channel's tech_pvt to null 03475 * to avoid ast_channel_free() trying to free it. 03476 */ 03477 c->tech_pvt = NULL; 03478 } 03479 ast_mutex_unlock(&iaxsl[callno]); 03480 if (option_verbose > 2) 03481 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name); 03482 return 0; 03483 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 3758 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, chan_iax2_pvt::mohinterpret, option_debug, PTR_TO_CALLNO, send_command(), ast_channel::tech_pvt, and wait_for_peercallno().
03759 { 03760 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03761 struct chan_iax2_pvt *pvt; 03762 int res = 0; 03763 03764 if (option_debug && iaxdebug) 03765 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition); 03766 03767 ast_mutex_lock(&iaxsl[callno]); 03768 pvt = iaxs[callno]; 03769 03770 if (wait_for_peercallno(pvt)) { 03771 res = -1; 03772 goto done; 03773 } 03774 03775 switch (condition) { 03776 case AST_CONTROL_HOLD: 03777 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03778 ast_moh_start(c, data, pvt->mohinterpret); 03779 goto done; 03780 } 03781 break; 03782 case AST_CONTROL_UNHOLD: 03783 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03784 ast_moh_stop(c); 03785 goto done; 03786 } 03787 } 03788 03789 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 03790 03791 done: 03792 ast_mutex_unlock(&iaxsl[callno]); 03793 03794 return res; 03795 }
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 10656 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_MATCHMORE, dpcache_lock, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
10657 { 10658 int res = 0; 10659 struct iax2_dpcache *dp; 10660 #if 0 10661 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10662 #endif 10663 if ((priority != 1) && (priority != 2)) 10664 return 0; 10665 ast_mutex_lock(&dpcache_lock); 10666 dp = find_cache(chan, data, context, exten, priority); 10667 if (dp) { 10668 if (dp->flags & CACHE_FLAG_MATCHMORE) 10669 res= 1; 10670 } 10671 ast_mutex_unlock(&dpcache_lock); 10672 if (!dp) { 10673 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10674 } 10675 return res; 10676 }
static int iax2_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5077 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05078 { 05079 if (argc < 3 || argc > 4) 05080 return RESULT_SHOWUSAGE; 05081 iaxdebug = 0; 05082 ast_cli(fd, "IAX2 Debugging Disabled\n"); 05083 return RESULT_SUCCESS; 05084 }
static int iax2_no_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5095 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05096 { 05097 if (argc < 4 || argc > 5) 05098 return RESULT_SHOWUSAGE; 05099 jb_setoutput(jb_error_output, jb_warning_output, NULL); 05100 jb_debug_output("\n"); 05101 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 05102 return RESULT_SUCCESS; 05103 }
static int iax2_no_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5086 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05087 { 05088 if (argc < 4 || argc > 5) 05089 return RESULT_SHOWUSAGE; 05090 iaxtrunkdebug = 0; 05091 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n"); 05092 return RESULT_SUCCESS; 05093 }
static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 8992 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
08993 { 08994 struct iax2_peer *peer = (struct iax2_peer *)data; 08995 peer->pokeexpire = -1; 08996 #ifdef SCHED_MULTITHREADED 08997 if (schedule_action(__iax2_poke_noanswer, data)) 08998 #endif 08999 __iax2_poke_noanswer(data); 09000 peer_unref(peer); 09001 return 0; 09002 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 9013 of file chan_iax2.c.
References iax2_peer::addr, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), iax2_peer::callno, DEFAULT_MAXMS, iax2_peer::dnsmgr, find_callno(), iax2_peer::historicms, iax2_destroy(), iax2_poke_noanswer(), iax2_sched_add(), IAX_COMMAND_POKE, iaxs, iaxsl, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, iax2_peer::maxms, iax2_peer::name, NEW_FORCE, peer_ref(), peer_unref(), chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, sched, send_command(), and iax2_peer::sockfd.
Referenced by __iax2_poke_peer_s(), iax2_poke_peer_cb(), poke_all_peers(), reg_source_db(), and update_registry().
09014 { 09015 int callno; 09016 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) { 09017 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 09018 immediately after clearing things out */ 09019 peer->lastms = 0; 09020 peer->historicms = 0; 09021 peer->pokeexpire = -1; 09022 peer->callno = 0; 09023 return 0; 09024 } 09025 09026 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 09027 if ((callno = peer->callno) > 0) { 09028 ast_log(LOG_NOTICE, "Still have a callno...\n"); 09029 ast_mutex_lock(&iaxsl[callno]); 09030 iax2_destroy(callno); 09031 ast_mutex_unlock(&iaxsl[callno]); 09032 } 09033 if (heldcall) 09034 ast_mutex_unlock(&iaxsl[heldcall]); 09035 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0); 09036 if (heldcall) 09037 ast_mutex_lock(&iaxsl[heldcall]); 09038 if (peer->callno < 1) { 09039 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 09040 return -1; 09041 } 09042 09043 /* Speed up retransmission times for this qualify call */ 09044 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 09045 iaxs[peer->callno]->peerpoke = peer; 09046 09047 /* Remove any pending pokeexpire task */ 09048 if (peer->pokeexpire > -1) { 09049 if (!ast_sched_del(sched, peer->pokeexpire)) { 09050 peer->pokeexpire = -1; 09051 peer_unref(peer); 09052 } 09053 } 09054 09055 /* Queue up a new task to handle no reply */ 09056 /* If the host is already unreachable then use the unreachable interval instead */ 09057 if (peer->lastms < 0) { 09058 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 09059 } else 09060 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 09061 09062 if (peer->pokeexpire == -1) 09063 peer_unref(peer); 09064 09065 /* And send the poke */ 09066 ast_mutex_lock(&iaxsl[callno]); 09067 if (iaxs[callno]) { 09068 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1); 09069 } 09070 ast_mutex_unlock(&iaxsl[callno]); 09071 09072 return 0; 09073 }
static int iax2_poke_peer_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9004 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
09005 { 09006 struct iax2_peer *peer = obj; 09007 09008 iax2_poke_peer(peer, 0); 09009 09010 return 0; 09011 }
static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 6595 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
06596 { 06597 struct iax2_peer *peer = (struct iax2_peer *)data; 06598 peer->pokeexpire = -1; 06599 #ifdef SCHED_MULTITHREADED 06600 if (schedule_action(__iax2_poke_peer_s, data)) 06601 #endif 06602 __iax2_poke_peer_s(data); 06603 return 0; 06604 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 2179 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().
02180 { 02181 struct ast_channel *c; 02182 struct chan_iax2_pvt *pvt = iaxs[callno]; 02183 02184 if (!pvt) 02185 return -1; 02186 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 02187 iax2_destroy_helper(pvt); 02188 ast_set_flag(pvt, IAX_ALREADYGONE); 02189 } 02190 c = pvt->owner; 02191 if (c) { 02192 c->tech_pvt = NULL; 02193 iax2_queue_hangup(callno); 02194 pvt->owner = NULL; 02195 ast_module_unref(ast_module_info->self); 02196 } 02197 return 0; 02198 }
static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 8668 of file chan_iax2.c.
References ast_atomic_fetchadd_int(), ast_cond_timedwait(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_samp2tv(), ast_tvadd(), ast_tvnow(), iax2_process_thread_cleanup(), IAX_TYPE_DYNAMIC, iaxactivethreadcount, iaxdynamicthreadcount, insert_idle_thread(), t, and thread.
Referenced by find_idle_thread(), and start_network_thread().
08669 { 08670 struct iax2_thread *thread = data; 08671 struct timeval tv; 08672 struct timespec ts; 08673 int put_into_idle = 0; 08674 08675 ast_atomic_fetchadd_int(&iaxactivethreadcount,1); 08676 pthread_cleanup_push(iax2_process_thread_cleanup, data); 08677 for(;;) { 08678 /* Wait for something to signal us to be awake */ 08679 ast_mutex_lock(&thread->lock); 08680 08681 /* Flag that we're ready to accept signals */ 08682 thread->ready_for_signal = 1; 08683 08684 /* Put into idle list if applicable */ 08685 if (put_into_idle) 08686 insert_idle_thread(thread); 08687 08688 if (thread->type == IAX_TYPE_DYNAMIC) { 08689 struct iax2_thread *t = NULL; 08690 /* Wait to be signalled or time out */ 08691 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08692 ts.tv_sec = tv.tv_sec; 08693 ts.tv_nsec = tv.tv_usec * 1000; 08694 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 08695 /* This thread was never put back into the available dynamic 08696 * thread list, so just go away. */ 08697 if (!put_into_idle) { 08698 ast_mutex_unlock(&thread->lock); 08699 break; 08700 } 08701 AST_LIST_LOCK(&dynamic_list); 08702 /* Account for the case where this thread is acquired *right* after a timeout */ 08703 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 08704 iaxdynamicthreadcount--; 08705 AST_LIST_UNLOCK(&dynamic_list); 08706 if (t) { 08707 /* This dynamic thread timed out waiting for a task and was 08708 * not acquired immediately after the timeout, 08709 * so it's time to go away. */ 08710 ast_mutex_unlock(&thread->lock); 08711 break; 08712 } 08713 /* Someone grabbed our thread *right* after we timed out. 08714 * Wait for them to set us up with something to do and signal 08715 * us to continue. */ 08716 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08717 ts.tv_sec = tv.tv_sec; 08718 ts.tv_nsec = tv.tv_usec * 1000; 08719 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) 08720 { 08721 ast_mutex_unlock(&thread->lock); 08722 break; 08723 } 08724 } 08725 } else { 08726 ast_cond_wait(&thread->cond, &thread->lock); 08727 } 08728 08729 /* Go back into our respective list */ 08730 put_into_idle = 1; 08731 08732 ast_mutex_unlock(&thread->lock); 08733 08734 if (thread->iostate == IAX_IOSTATE_IDLE) 08735 continue; 08736 08737 /* Add ourselves to the active list now */ 08738 AST_LIST_LOCK(&active_list); 08739 AST_LIST_INSERT_HEAD(&active_list, thread, list); 08740 AST_LIST_UNLOCK(&active_list); 08741 08742 /* See what we need to do */ 08743 switch(thread->iostate) { 08744 case IAX_IOSTATE_READY: 08745 thread->actions++; 08746 thread->iostate = IAX_IOSTATE_PROCESSING; 08747 socket_process(thread); 08748 handle_deferred_full_frames(thread); 08749 break; 08750 case IAX_IOSTATE_SCHEDREADY: 08751 thread->actions++; 08752 thread->iostate = IAX_IOSTATE_PROCESSING; 08753 #ifdef SCHED_MULTITHREADED 08754 thread->schedfunc(thread->scheddata); 08755 #endif 08756 break; 08757 } 08758 time(&thread->checktime); 08759 thread->iostate = IAX_IOSTATE_IDLE; 08760 #ifdef DEBUG_SCHED_MULTITHREAD 08761 thread->curfunc[0]='\0'; 08762 #endif 08763 08764 /* Now... remove ourselves from the active list, and return to the idle list */ 08765 AST_LIST_LOCK(&active_list); 08766 AST_LIST_REMOVE(&active_list, thread, list); 08767 AST_LIST_UNLOCK(&active_list); 08768 08769 /* Make sure another frame didn't sneak in there after we thought we were done. */ 08770 handle_deferred_full_frames(thread); 08771 } 08772 08773 /*!\note For some reason, idle threads are exiting without being removed 08774 * from an idle list, which is causing memory corruption. Forcibly remove 08775 * it from the list, if it's there. 08776 */ 08777 AST_LIST_LOCK(&idle_list); 08778 AST_LIST_REMOVE(&idle_list, thread, list); 08779 AST_LIST_UNLOCK(&idle_list); 08780 08781 AST_LIST_LOCK(&dynamic_list); 08782 AST_LIST_REMOVE(&dynamic_list, thread, list); 08783 AST_LIST_UNLOCK(&dynamic_list); 08784 08785 /* I am exiting here on my own volition, I need to clean up my own data structures 08786 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 08787 */ 08788 pthread_cleanup_pop(1); 08789 08790 return NULL; 08791 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 8659 of file chan_iax2.c.
References ast_atomic_dec_and_test(), ast_cond_destroy(), ast_mutex_destroy(), free, iaxactivethreadcount, and thread.
Referenced by iax2_process_thread().
08660 { 08661 struct iax2_thread *thread = data; 08662 ast_mutex_destroy(&thread->lock); 08663 ast_cond_destroy(&thread->cond); 08664 free(thread); 08665 ast_atomic_dec_and_test(&iaxactivethreadcount); 08666 }
static int iax2_prov_cmd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 8947 of file chan_iax2.c.
References ast_cli(), iax2_provision(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
08948 { 08949 int force = 0; 08950 int res; 08951 if (argc < 4) 08952 return RESULT_SHOWUSAGE; 08953 if ((argc > 4)) { 08954 if (!strcasecmp(argv[4], "forced")) 08955 force = 1; 08956 else 08957 return RESULT_SHOWUSAGE; 08958 } 08959 res = iax2_provision(NULL, -1, argv[2], argv[3], force); 08960 if (res < 0) 08961 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]); 08962 else if (res < 1) 08963 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]); 08964 else 08965 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : ""); 08966 return RESULT_SUCCESS; 08967 }
static char* iax2_prov_complete_template_3rd | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 8850 of file chan_iax2.c.
References iax_prov_complete_template().
08851 { 08852 if (pos != 3) 08853 return NULL; 08854 return iax_prov_complete_template(line, word, pos, state); 08855 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 8857 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_unlock(), AST_SCHED_DEL, ast_set_flag, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, create_addr(), find_callno_locked(), iax2_sched_add(), IAX_COMMAND_PROVISION, iax_ie_append_raw(), IAX_IE_PROVISIONING, IAX_PROVISION, iax_provision_build(), iaxs, iaxsl, NEW_FORCE, option_debug, iax_ie_data::pos, sched, and send_command().
Referenced by check_provisioning(), iax2_prov_app(), and iax2_prov_cmd().
08858 { 08859 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 08860 is found for template */ 08861 struct iax_ie_data provdata; 08862 struct iax_ie_data ied; 08863 unsigned int sig; 08864 struct sockaddr_in sin; 08865 int callno; 08866 struct create_addr_info cai; 08867 08868 memset(&cai, 0, sizeof(cai)); 08869 08870 if (option_debug) 08871 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template); 08872 08873 if (iax_provision_build(&provdata, &sig, template, force)) { 08874 if (option_debug) 08875 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template); 08876 return 0; 08877 } 08878 08879 if (end) { 08880 memcpy(&sin, end, sizeof(sin)); 08881 cai.sockfd = sockfd; 08882 } else if (create_addr(dest, NULL, &sin, &cai)) 08883 return -1; 08884 08885 /* Build the rest of the message */ 08886 memset(&ied, 0, sizeof(ied)); 08887 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 08888 08889 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 08890 if (!callno) 08891 return -1; 08892 08893 if (iaxs[callno]) { 08894 /* Schedule autodestruct in case they don't ever give us anything back */ 08895 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 08896 iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno); 08897 ast_set_flag(iaxs[callno], IAX_PROVISION); 08898 /* Got a call number now, so go ahead and send the provisioning information */ 08899 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 08900 } 08901 ast_mutex_unlock(&iaxsl[callno]); 08902 08903 return 1; 08904 }
static int iax2_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2303 of file chan_iax2.c.
References ast_cli(), ast_set_flag, ast_test_flag, expire_registry(), find_peer(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, peer_ref(), peer_unref(), reload_config(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02304 { 02305 struct iax2_peer *peer; 02306 02307 if (argc != 4) 02308 return RESULT_SHOWUSAGE; 02309 if (!strcmp(argv[3],"all")) { 02310 reload_config(); 02311 ast_cli(fd, "OK cache is flushed.\n"); 02312 } else if ((peer = find_peer(argv[3], 0))) { 02313 if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 02314 ast_set_flag(peer, IAX_RTAUTOCLEAR); 02315 expire_registry(peer_ref(peer)); 02316 ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]); 02317 } else { 02318 ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]); 02319 } 02320 peer_unref(peer); 02321 } else { 02322 ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]); 02323 } 02324 02325 return RESULT_SUCCESS; 02326 }
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 1789 of file chan_iax2.c.
References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_control_data(), DEADLOCK_AVOIDANCE, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by socket_process().
01791 { 01792 for (;;) { 01793 if (iaxs[callno] && iaxs[callno]->owner) { 01794 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01795 /* Avoid deadlock by pausing and trying again */ 01796 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01797 } else { 01798 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 01799 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01800 break; 01801 } 01802 } else 01803 break; 01804 } 01805 return 0; 01806 }
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 1727 of file chan_iax2.c.
References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), DEADLOCK_AVOIDANCE, f, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by __attempt_transmit(), __auto_congest(), __do_deliver(), __get_from_jb(), and socket_process().
01728 { 01729 for (;;) { 01730 if (iaxs[callno] && iaxs[callno]->owner) { 01731 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01732 /* Avoid deadlock by pausing and trying again */ 01733 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01734 } else { 01735 ast_queue_frame(iaxs[callno]->owner, f); 01736 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01737 break; 01738 } 01739 } else 01740 break; 01741 } 01742 return 0; 01743 }
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 1758 of file chan_iax2.c.
References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), DEADLOCK_AVOIDANCE, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by iax2_predestroy().
01759 { 01760 for (;;) { 01761 if (iaxs[callno] && iaxs[callno]->owner) { 01762 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01763 /* Avoid deadlock by pausing and trying again */ 01764 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01765 } else { 01766 ast_queue_hangup(iaxs[callno]->owner); 01767 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01768 break; 01769 } 01770 } else 01771 break; 01772 } 01773 return 0; 01774 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3549 of file chan_iax2.c.
References ast_log(), and LOG_NOTICE.
03550 { 03551 ast_log(LOG_NOTICE, "I should never be called! Hanging up.\n"); 03552 return NULL; 03553 }
static int iax2_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 6071 of file chan_iax2.c.
References ast_calloc, ast_copy_string(), ast_dnsmgr_lookup(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), copy(), iax2_registry::entry, free, hostname, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, LOG_WARNING, and secret.
Referenced by set_config().
06072 { 06073 struct iax2_registry *reg; 06074 char copy[256]; 06075 char *username, *hostname, *secret; 06076 char *porta; 06077 char *stringp=NULL; 06078 06079 if (!value) 06080 return -1; 06081 ast_copy_string(copy, value, sizeof(copy)); 06082 stringp=copy; 06083 username = strsep(&stringp, "@"); 06084 hostname = strsep(&stringp, "@"); 06085 if (!hostname) { 06086 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 06087 return -1; 06088 } 06089 stringp=username; 06090 username = strsep(&stringp, ":"); 06091 secret = strsep(&stringp, ":"); 06092 stringp=hostname; 06093 hostname = strsep(&stringp, ":"); 06094 porta = strsep(&stringp, ":"); 06095 06096 if (porta && !atoi(porta)) { 06097 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 06098 return -1; 06099 } 06100 if (!(reg = ast_calloc(1, sizeof(*reg)))) 06101 return -1; 06102 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) { 06103 free(reg); 06104 return -1; 06105 } 06106 ast_copy_string(reg->username, username, sizeof(reg->username)); 06107 if (secret) 06108 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 06109 reg->expire = -1; 06110 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 06111 reg->addr.sin_family = AF_INET; 06112 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 06113 AST_LIST_LOCK(®istrations); 06114 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 06115 AST_LIST_UNLOCK(®istrations); 06116 06117 return 0; 06118 }
static int iax2_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 10375 of file chan_iax2.c.
References reload_config().
10376 { 10377 return reload_config(); 10378 }
static struct ast_channel * iax2_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 9085 of file chan_iax2.c.
References ast_best_codec(), AST_CAUSE_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_flags, ast_getformatname(), ast_hangup(), ast_iax2_new(), ast_log(), ast_mutex_unlock(), AST_STATE_DOWN, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_translator_best_choice(), create_addr(), find_callno_locked(), 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::name, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), chan_iax2_pvt::peer, ast_channel::readformat, and ast_channel::writeformat.
09086 { 09087 int callno; 09088 int res; 09089 int fmt, native; 09090 struct sockaddr_in sin; 09091 struct ast_channel *c; 09092 struct parsed_dial_string pds; 09093 struct create_addr_info cai; 09094 char *tmpstr; 09095 09096 memset(&pds, 0, sizeof(pds)); 09097 tmpstr = ast_strdupa(data); 09098 parse_dial_string(tmpstr, &pds); 09099 09100 if (ast_strlen_zero(pds.peer)) { 09101 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 09102 return NULL; 09103 } 09104 09105 memset(&cai, 0, sizeof(cai)); 09106 cai.capability = iax2_capability; 09107 09108 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09109 09110 /* Populate our address from the given */ 09111 if (create_addr(pds.peer, NULL, &sin, &cai)) { 09112 *cause = AST_CAUSE_UNREGISTERED; 09113 return NULL; 09114 } 09115 09116 if (pds.port) 09117 sin.sin_port = htons(atoi(pds.port)); 09118 09119 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 09120 if (callno < 1) { 09121 ast_log(LOG_WARNING, "Unable to create call\n"); 09122 *cause = AST_CAUSE_CONGESTION; 09123 return NULL; 09124 } 09125 09126 /* If this is a trunk, update it now */ 09127 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09128 if (ast_test_flag(&cai, IAX_TRUNK)) { 09129 int new_callno; 09130 if ((new_callno = make_trunk(callno, 1)) != -1) 09131 callno = new_callno; 09132 } 09133 iaxs[callno]->maxtime = cai.maxtime; 09134 if (cai.found) 09135 ast_string_field_set(iaxs[callno], host, pds.peer); 09136 09137 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 09138 09139 ast_mutex_unlock(&iaxsl[callno]); 09140 09141 if (c) { 09142 /* Choose a format we can live with */ 09143 if (c->nativeformats & format) 09144 c->nativeformats &= format; 09145 else { 09146 native = c->nativeformats; 09147 fmt = format; 09148 res = ast_translator_best_choice(&fmt, &native); 09149 if (res < 0) { 09150 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 09151 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 09152 ast_hangup(c); 09153 return NULL; 09154 } 09155 c->nativeformats = native; 09156 } 09157 c->readformat = ast_best_codec(c->nativeformats); 09158 c->writeformat = c->readformat; 09159 } 09160 09161 return c; 09162 }
static int iax2_sched_add | ( | struct sched_context * | con, | |
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 985 of file chan_iax2.c.
References ast_sched_add(), sched_lock, and signal_condition().
Referenced by __attempt_transmit(), __find_callno(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), auth_fail(), iax2_ack_registry(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_poke_peer(), iax2_provision(), make_trunk(), network_thread(), reg_source_db(), socket_process(), update_jbsched(), and update_registry().
00986 { 00987 int res; 00988 00989 res = ast_sched_add(con, when, callback, data); 00990 signal_condition(&sched_lock, &sched_cond); 00991 00992 return res; 00993 }
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 4388 of file chan_iax2.c.
References iax_frame::af, iax_frame::afdatalen, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_test_flag, calc_timestamp(), ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, chan_iax2_pvt::callno, iax_frame::callno, compress_subclass(), ast_iax2_full_hdr::csub, iax_frame::data, ast_frame::data, ast_frame::datalen, iax_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, encrypt_frame(), f, iax_frame::final, ast_frame::frametype, iax2_transmit(), iax2_trunk_queue(), IAX_COMMAND_ACK, IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_showframe(), IAX_TRUNK, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, chan_iax2_pvt::lastsent, chan_iax2_pvt::lastvsent, LOG_WARNING, MAX_RETRY_TIME, MIN_RETRY_TIME, ast_iax2_full_hdr::oseqno, chan_iax2_pvt::oseqno, iax_frame::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, iax_frame::retries, iax_frame::retrytime, ast_iax2_full_hdr::scallno, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, iax_frame::transfer, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, ast_iax2_mini_hdr::ts, ast_iax2_video_hdr::ts, ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_full_hdr::type, and ast_iax2_video_hdr::zeros.
Referenced by __send_command(), iax2_write(), and socket_process().
04389 { 04390 /* Queue a packet for delivery on a given private structure. Use "ts" for 04391 timestamp, or calculate if ts is 0. Send immediately without retransmission 04392 or delayed, with retransmission */ 04393 struct ast_iax2_full_hdr *fh; 04394 struct ast_iax2_mini_hdr *mh; 04395 struct ast_iax2_video_hdr *vh; 04396 struct { 04397 struct iax_frame fr2; 04398 unsigned char buffer[4096]; 04399 } frb; 04400 struct iax_frame *fr; 04401 int res; 04402 int sendmini=0; 04403 unsigned int lastsent; 04404 unsigned int fts; 04405 04406 frb.fr2.afdatalen = sizeof(frb.buffer); 04407 04408 if (!pvt) { 04409 ast_log(LOG_WARNING, "No private structure for packet?\n"); 04410 return -1; 04411 } 04412 04413 lastsent = pvt->lastsent; 04414 04415 /* Calculate actual timestamp */ 04416 fts = calc_timestamp(pvt, ts, f); 04417 04418 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 04419 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 04420 * increment the "predicted timestamps" for voice, if we're predecting */ 04421 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 04422 return 0; 04423 04424 04425 if ((ast_test_flag(pvt, IAX_TRUNK) || 04426 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 04427 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 04428 /* High two bytes are the same on timestamp, or sending on a trunk */ && 04429 (f->frametype == AST_FRAME_VOICE) 04430 /* is a voice frame */ && 04431 (f->subclass == pvt->svoiceformat) 04432 /* is the same type */ ) { 04433 /* Force immediate rather than delayed transmission */ 04434 now = 1; 04435 /* Mark that mini-style frame is appropriate */ 04436 sendmini = 1; 04437 } 04438 if ( f->frametype == AST_FRAME_VIDEO ) { 04439 /* 04440 * If the lower 15 bits of the timestamp roll over, or if 04441 * the video format changed then send a full frame. 04442 * Otherwise send a mini video frame 04443 */ 04444 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 04445 ((f->subclass & ~0x1) == pvt->svideoformat) 04446 ) { 04447 now = 1; 04448 sendmini = 1; 04449 } else { 04450 now = 0; 04451 sendmini = 0; 04452 } 04453 pvt->lastvsent = fts; 04454 } 04455 /* Allocate an iax_frame */ 04456 if (now) { 04457 fr = &frb.fr2; 04458 } else 04459 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)); 04460 if (!fr) { 04461 ast_log(LOG_WARNING, "Out of memory\n"); 04462 return -1; 04463 } 04464 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 04465 iax_frame_wrap(fr, f); 04466 04467 fr->ts = fts; 04468 fr->callno = pvt->callno; 04469 fr->transfer = transfer; 04470 fr->final = final; 04471 if (!sendmini) { 04472 /* We need a full frame */ 04473 if (seqno > -1) 04474 fr->oseqno = seqno; 04475 else 04476 fr->oseqno = pvt->oseqno++; 04477 fr->iseqno = pvt->iseqno; 04478 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr)); 04479 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 04480 fh->ts = htonl(fr->ts); 04481 fh->oseqno = fr->oseqno; 04482 if (transfer) { 04483 fh->iseqno = 0; 04484 } else 04485 fh->iseqno = fr->iseqno; 04486 /* Keep track of the last thing we've acknowledged */ 04487 if (!transfer) 04488 pvt->aseqno = fr->iseqno; 04489 fh->type = fr->af.frametype & 0xFF; 04490 if (fr->af.frametype == AST_FRAME_VIDEO) 04491 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 04492 else 04493 fh->csub = compress_subclass(fr->af.subclass); 04494 if (transfer) { 04495 fr->dcallno = pvt->transfercallno; 04496 } else 04497 fr->dcallno = pvt->peercallno; 04498 fh->dcallno = htons(fr->dcallno); 04499 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 04500 fr->data = fh; 04501 fr->retries = 0; 04502 /* Retry after 2x the ping time has passed */ 04503 fr->retrytime = pvt->pingtime * 2; 04504 if (fr->retrytime < MIN_RETRY_TIME) 04505 fr->retrytime = MIN_RETRY_TIME; 04506 if (fr->retrytime > MAX_RETRY_TIME) 04507 fr->retrytime = MAX_RETRY_TIME; 04508 /* Acks' don't get retried */ 04509 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 04510 fr->retries = -1; 04511 else if (f->frametype == AST_FRAME_VOICE) 04512 pvt->svoiceformat = f->subclass; 04513 else if (f->frametype == AST_FRAME_VIDEO) 04514 pvt->svideoformat = f->subclass & ~0x1; 04515 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04516 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04517 if (iaxdebug) { 04518 if (fr->transfer) 04519 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04520 else 04521 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04522 } 04523 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 04524 } else 04525 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04526 } 04527 04528 if (now) { 04529 res = send_packet(fr); 04530 } else 04531 res = iax2_transmit(fr); 04532 } else { 04533 if (ast_test_flag(pvt, IAX_TRUNK)) { 04534 iax2_trunk_queue(pvt, fr); 04535 res = 0; 04536 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 04537 /* Video frame have no sequence number */ 04538 fr->oseqno = -1; 04539 fr->iseqno = -1; 04540 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr)); 04541 vh->zeros = 0; 04542 vh->callno = htons(0x8000 | fr->callno); 04543 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 04544 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 04545 fr->data = vh; 04546 fr->retries = -1; 04547 res = send_packet(fr); 04548 } else { 04549 /* Mini-frames have no sequence number */ 04550 fr->oseqno = -1; 04551 fr->iseqno = -1; 04552 /* Mini frame will do */ 04553 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr)); 04554 mh->callno = htons(fr->callno); 04555 mh->ts = htons(fr->ts & 0xFFFF); 04556 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 04557 fr->data = mh; 04558 fr->retries = -1; 04559 if (pvt->transferring == TRANSFER_MEDIAPASS) 04560 fr->transfer = 1; 04561 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04562 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04563 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 04564 } else 04565 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04566 } 04567 res = send_packet(fr); 04568 } 04569 } 04570 return res; 04571 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 2834 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02835 { 02836 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 02837 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 2829 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.
02830 { 02831 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1); 02832 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 2822 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02823 { 02824 02825 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 02826 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 02827 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 3507 of file chan_iax2.c.
References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_malloc, ast_mutex_lock(), ast_mutex_unlock(), AST_OPTION_FLAG_REQUEST, AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, errno, free, iaxs, iaxsl, PTR_TO_CALLNO, send_command_locked(), ast_channel::tech_pvt, and wait_for_peercallno().
03508 { 03509 struct ast_option_header *h; 03510 int res; 03511 03512 switch (option) { 03513 case AST_OPTION_TXGAIN: 03514 case AST_OPTION_RXGAIN: 03515 /* these two cannot be sent, because they require a result */ 03516 errno = ENOSYS; 03517 return -1; 03518 default: 03519 { 03520 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03521 struct chan_iax2_pvt *pvt; 03522 03523 ast_mutex_lock(&iaxsl[callno]); 03524 pvt = iaxs[callno]; 03525 03526 if (wait_for_peercallno(pvt)) { 03527 ast_mutex_unlock(&iaxsl[callno]); 03528 return -1; 03529 } 03530 03531 ast_mutex_unlock(&iaxsl[callno]); 03532 03533 if (!(h = ast_malloc(datalen + sizeof(*h)))) { 03534 return -1; 03535 } 03536 03537 h->flag = AST_OPTION_FLAG_REQUEST; 03538 h->option = htons(option); 03539 memcpy(h->data, data, datalen); 03540 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 03541 AST_CONTROL_OPTION, 0, (unsigned char *) h, 03542 datalen + sizeof(*h), -1); 03543 free(h); 03544 return res; 03545 } 03546 } 03547 }
static int iax2_show_cache | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2507 of file chan_iax2.c.
References ast_cli(), ast_copy_string(), 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, dpcache_lock, iax2_dpcache::expiry, iax2_dpcache::exten, iax2_dpcache::flags, iax2_dpcache::next, iax2_dpcache::peercontext, RESULT_SUCCESS, s, and iax2_dpcache::waiters.
02508 { 02509 struct iax2_dpcache *dp; 02510 char tmp[1024], *pc; 02511 int s; 02512 int x,y; 02513 struct timeval tv; 02514 gettimeofday(&tv, NULL); 02515 ast_mutex_lock(&dpcache_lock); 02516 dp = dpcache; 02517 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 02518 while(dp) { 02519 s = dp->expiry.tv_sec - tv.tv_sec; 02520 tmp[0] = '\0'; 02521 if (dp->flags & CACHE_FLAG_EXISTS) 02522 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 02523 if (dp->flags & CACHE_FLAG_NONEXISTENT) 02524 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 02525 if (dp->flags & CACHE_FLAG_CANEXIST) 02526 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 02527 if (dp->flags & CACHE_FLAG_PENDING) 02528 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 02529 if (dp->flags & CACHE_FLAG_TIMEOUT) 02530 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 02531 if (dp->flags & CACHE_FLAG_TRANSMITTED) 02532 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 02533 if (dp->flags & CACHE_FLAG_MATCHMORE) 02534 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 02535 if (dp->flags & CACHE_FLAG_UNKNOWN) 02536 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 02537 /* Trim trailing pipe */ 02538 if (!ast_strlen_zero(tmp)) 02539 tmp[strlen(tmp) - 1] = '\0'; 02540 else 02541 ast_copy_string(tmp, "(none)", sizeof(tmp)); 02542 y=0; 02543 pc = strchr(dp->peercontext, '@'); 02544 if (!pc) 02545 pc = dp->peercontext; 02546 else 02547 pc++; 02548 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 02549 if (dp->waiters[x] > -1) 02550 y++; 02551 if (s > 0) 02552 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 02553 else 02554 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 02555 dp = dp->next; 02556 } 02557 ast_mutex_unlock(&dpcache_lock); 02558 return RESULT_SUCCESS; 02559 }
static int iax2_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4915 of file chan_iax2.c.
References ARRAY_LEN, ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, iax2_registry::callno, jb_info::current, iax_rr::delay, FORMAT, FORMAT2, IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), jb_info::jitter, jb_info::min, chan_iax2_pvt::remote_rr, RESULT_SHOWUSAGE, RESULT_SUCCESS, and S_OR.
04916 { 04917 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" 04918 #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" 04919 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 04920 int x; 04921 int numchans = 0; 04922 04923 if (argc != 3) 04924 return RESULT_SHOWUSAGE; 04925 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format"); 04926 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 04927 ast_mutex_lock(&iaxsl[x]); 04928 if (iaxs[x]) { 04929 int lag, jitter, localdelay; 04930 jb_info jbinfo; 04931 04932 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04933 jb_getinfo(iaxs[x]->jb, &jbinfo); 04934 jitter = jbinfo.jitter; 04935 localdelay = jbinfo.current - jbinfo.min; 04936 } else { 04937 jitter = -1; 04938 localdelay = 0; 04939 } 04940 lag = iaxs[x]->remote_rr.delay; 04941 ast_cli(fd, FORMAT, 04942 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04943 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 04944 S_OR(iaxs[x]->username, "(None)"), 04945 iaxs[x]->callno, iaxs[x]->peercallno, 04946 iaxs[x]->oseqno, iaxs[x]->iseqno, 04947 lag, 04948 jitter, 04949 localdelay, 04950 ast_getformatname(iaxs[x]->voiceformat) ); 04951 numchans++; 04952 } 04953 ast_mutex_unlock(&iaxsl[x]); 04954 } 04955 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04956 return RESULT_SUCCESS; 04957 #undef FORMAT 04958 #undef FORMAT2 04959 #undef FORMATB 04960 }
static int iax2_show_firmware | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4826 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.
04827 { 04828 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" 04829 #if !defined(__FreeBSD__) 04830 #define FORMAT "%-15.15s %-15d %-15d\n" 04831 #else /* __FreeBSD__ */ 04832 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */ 04833 #endif /* __FreeBSD__ */ 04834 struct iax_firmware *cur; 04835 if ((argc != 3) && (argc != 4)) 04836 return RESULT_SHOWUSAGE; 04837 ast_mutex_lock(&waresl.lock); 04838 04839 ast_cli(fd, FORMAT2, "Device", "Version", "Size"); 04840 for (cur = waresl.wares;cur;cur = cur->next) { 04841 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 04842 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version), 04843 (int)ntohl(cur->fwh->datalen)); 04844 } 04845 ast_mutex_unlock(&waresl.lock); 04846 return RESULT_SUCCESS; 04847 #undef FORMAT 04848 #undef FORMAT2 04849 }
static int iax2_show_netstats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5038 of file chan_iax2.c.
References ast_cli(), ast_cli_netstats(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05039 { 05040 int numchans = 0; 05041 if (argc != 3) 05042 return RESULT_SHOWUSAGE; 05043 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 05044 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n"); 05045 numchans = ast_cli_netstats(NULL, fd, 1); 05046 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 05047 return RESULT_SUCCESS; 05048 }
static int iax2_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 2397 of file chan_iax2.c.
References iax2_peer::addr, ast_callerid_merge(), ast_cli(), ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, iax2_peer::capability, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::defaddr, iax2_peer::expire, find_peer(), iax2_peer::ha, IAX_DYNAMIC, iax2_peer::mailbox, iax2_peer::name, peer_status(), peer_unref(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax2_peer::prefs, RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_peer::secret, iax2_peer::smoothing, and iax2_peer::username.
02398 { 02399 char status[30]; 02400 char cbuf[256]; 02401 struct iax2_peer *peer; 02402 char codec_buf[512]; 02403 int x = 0, codec = 0, load_realtime = 0; 02404 02405 if (argc < 4) 02406 return RESULT_SHOWUSAGE; 02407 02408 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 02409 02410 peer = find_peer(argv[3], load_realtime); 02411 if (peer) { 02412 ast_cli(fd,"\n\n"); 02413 ast_cli(fd, " * Name : %s\n", peer->name); 02414 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 02415 ast_cli(fd, " Context : %s\n", peer->context); 02416 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 02417 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No"); 02418 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 02419 ast_cli(fd, " Expire : %d\n", peer->expire); 02420 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 02421 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)); 02422 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 02423 ast_cli(fd, " Username : %s\n", peer->username); 02424 ast_cli(fd, " Codecs : "); 02425 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 02426 ast_cli(fd, "%s\n", codec_buf); 02427 02428 ast_cli(fd, " Codec Order : ("); 02429 for(x = 0; x < 32 ; x++) { 02430 codec = ast_codec_pref_index(&peer->prefs,x); 02431 if(!codec) 02432 break; 02433 ast_cli(fd, "%s", ast_getformatname(codec)); 02434 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 02435 ast_cli(fd, "|"); 02436 } 02437 02438 if (!x) 02439 ast_cli(fd, "none"); 02440 ast_cli(fd, ")\n"); 02441 02442 ast_cli(fd, " Status : "); 02443 peer_status(peer, status, sizeof(status)); 02444 ast_cli(fd, "%s\n",status); 02445 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 02446 ast_cli(fd,"\n"); 02447 peer_unref(peer); 02448 } else { 02449 ast_cli(fd,"Peer %s not found.\n", argv[3]); 02450 ast_cli(fd,"\n"); 02451 } 02452 02453 return RESULT_SUCCESS; 02454 }
static int iax2_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4815 of file chan_iax2.c.
References __iax2_show_peers().
04816 { 04817 return __iax2_show_peers(0, fd, NULL, argc, argv); 04818 }
static int iax2_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4887 of file chan_iax2.c.
References iax2_registry::addr, ast_cli(), ast_copy_string(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax2_registry::dnsmgr, iax2_registry::entry, FORMAT, FORMAT2, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_registry::us, and iax2_registry::username.
04888 { 04889 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 04890 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 04891 struct iax2_registry *reg = NULL; 04892 04893 char host[80]; 04894 char perceived[80]; 04895 if (argc != 3) 04896 return RESULT_SHOWUSAGE; 04897 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 04898 AST_LIST_LOCK(®istrations); 04899 AST_LIST_TRAVERSE(®istrations, reg, entry) { 04900 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 04901 if (reg->us.sin_addr.s_addr) 04902 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 04903 else 04904 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 04905 ast_cli(fd, FORMAT, host, 04906 (reg->dnsmgr) ? "Y" : "N", 04907 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 04908 } 04909 AST_LIST_UNLOCK(®istrations); 04910 return RESULT_SUCCESS; 04911 #undef FORMAT 04912 #undef FORMAT2 04913 }
static int iax2_show_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2481 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, iax_frame::list, ast_iax2_queue::queue, RESULT_SHOWUSAGE, RESULT_SUCCESS, and iax_frame::retries.
02482 { 02483 struct iax_frame *cur; 02484 int cnt = 0, dead=0, final=0; 02485 02486 if (argc != 3) 02487 return RESULT_SHOWUSAGE; 02488 02489 AST_LIST_LOCK(&iaxq.queue); 02490 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 02491 if (cur->retries < 0) 02492 dead++; 02493 if (cur->final) 02494 final++; 02495 cnt++; 02496 } 02497 AST_LIST_UNLOCK(&iaxq.queue); 02498 02499 ast_cli(fd, " IAX Statistics\n"); 02500 ast_cli(fd, "---------------------\n"); 02501 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 02502 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 02503 02504 return RESULT_SUCCESS; 02505 }
static int iax2_show_threads | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4756 of file chan_iax2.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, IAX_TYPE_DYNAMIC, iaxthreadcount, iax2_thread::list, RESULT_SHOWUSAGE, RESULT_SUCCESS, t, and thread.
04757 { 04758 struct iax2_thread *thread = NULL; 04759 time_t t; 04760 int threadcount = 0, dynamiccount = 0; 04761 char type; 04762 04763 if (argc != 3) 04764 return RESULT_SHOWUSAGE; 04765 04766 ast_cli(fd, "IAX2 Thread Information\n"); 04767 time(&t); 04768 ast_cli(fd, "Idle Threads:\n"); 04769 AST_LIST_LOCK(&idle_list); 04770 AST_LIST_TRAVERSE(&idle_list, thread, list) { 04771 #ifdef DEBUG_SCHED_MULTITHREAD 04772 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04773 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04774 #else 04775 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04776 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04777 #endif 04778 threadcount++; 04779 } 04780 AST_LIST_UNLOCK(&idle_list); 04781 ast_cli(fd, "Active Threads:\n"); 04782 AST_LIST_LOCK(&active_list); 04783 AST_LIST_TRAVERSE(&active_list, thread, list) { 04784 if (thread->type == IAX_TYPE_DYNAMIC) 04785 type = 'D'; 04786 else 04787 type = 'P'; 04788 #ifdef DEBUG_SCHED_MULTITHREAD 04789 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 04790 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04791 #else 04792 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 04793 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04794 #endif 04795 threadcount++; 04796 } 04797 AST_LIST_UNLOCK(&active_list); 04798 ast_cli(fd, "Dynamic Threads:\n"); 04799 AST_LIST_LOCK(&dynamic_list); 04800 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 04801 #ifdef DEBUG_SCHED_MULTITHREAD 04802 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04803 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04804 #else 04805 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04806 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04807 #endif 04808 dynamiccount++; 04809 } 04810 AST_LIST_UNLOCK(&dynamic_list); 04811 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 04812 return RESULT_SUCCESS; 04813 }
static int iax2_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4573 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_cli(), ast_copy_string(), 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, iax2_user::inkeys, iax2_user::name, RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_user::secret, and user_unref().
04574 { 04575 regex_t regexbuf; 04576 int havepattern = 0; 04577 04578 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 04579 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 04580 04581 struct iax2_user *user = NULL; 04582 char auth[90]; 04583 char *pstr = ""; 04584 struct ao2_iterator i; 04585 04586 switch (argc) { 04587 case 5: 04588 if (!strcasecmp(argv[3], "like")) { 04589 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04590 return RESULT_SHOWUSAGE; 04591 havepattern = 1; 04592 } else 04593 return RESULT_SHOWUSAGE; 04594 case 3: 04595 break; 04596 default: 04597 return RESULT_SHOWUSAGE; 04598 } 04599 04600 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 04601 i = ao2_iterator_init(users, 0); 04602 for (user = ao2_iterator_next(&i); user; 04603 user_unref(user), user = ao2_iterator_next(&i)) { 04604 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 04605 continue; 04606 04607 if (!ast_strlen_zero(user->secret)) { 04608 ast_copy_string(auth,user->secret,sizeof(auth)); 04609 } else if (!ast_strlen_zero(user->inkeys)) { 04610 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 04611 } else 04612 ast_copy_string(auth, "-no secret-", sizeof(auth)); 04613 04614 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 04615 pstr = "REQ Only"; 04616 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 04617 pstr = "Disabled"; 04618 else 04619 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 04620 04621 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 04622 user->contexts ? user->contexts->context : context, 04623 user->ha ? "Yes" : "No", pstr); 04624 } 04625 04626 if (havepattern) 04627 regfree(®exbuf); 04628 04629 return RESULT_SUCCESS; 04630 #undef FORMAT 04631 #undef FORMAT2 04632 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 3555 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.
03556 { 03557 int res; 03558 struct iax_ie_data ied0; 03559 struct iax_ie_data ied1; 03560 unsigned int transferid = (unsigned int)ast_random(); 03561 memset(&ied0, 0, sizeof(ied0)); 03562 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 03563 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 03564 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 03565 03566 memset(&ied1, 0, sizeof(ied1)); 03567 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 03568 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 03569 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 03570 03571 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 03572 if (res) 03573 return -1; 03574 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 03575 if (res) 03576 return -1; 03577 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03578 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03579 return 0; 03580 }
static int iax2_test_losspct | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2328 of file chan_iax2.c.
References RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02329 { 02330 if (argc != 4) 02331 return RESULT_SHOWUSAGE; 02332 02333 test_losspct = atoi(argv[3]); 02334 02335 return RESULT_SUCCESS; 02336 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 3797 of file chan_iax2.c.
References ast_copy_string(), AST_FRAME_IAX, ast_log(), chan_iax2_pvt::callno, IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, ast_channel::name, option_debug, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03798 { 03799 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03800 struct iax_ie_data ied; 03801 char tmp[256], *context; 03802 ast_copy_string(tmp, dest, sizeof(tmp)); 03803 context = strchr(tmp, '@'); 03804 if (context) { 03805 *context = '\0'; 03806 context++; 03807 } 03808 memset(&ied, 0, sizeof(ied)); 03809 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 03810 if (context) 03811 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 03812 if (option_debug) 03813 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest); 03814 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 03815 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2793 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, AST_PTHREADT_NULL, ast_iax2_queue::count, iaxq, ast_iax2_queue::queue, sched_lock, iax_frame::sentyet, and signal_condition().
Referenced by iax2_send().
02794 { 02795 /* Lock the queue and place this packet at the end */ 02796 /* By setting this to 0, the network thread will send it for us, and 02797 queue retransmission if necessary */ 02798 fr->sentyet = 0; 02799 AST_LIST_LOCK(&iaxq.queue); 02800 AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list); 02801 iaxq.count++; 02802 AST_LIST_UNLOCK(&iaxq.queue); 02803 /* Wake up the network and scheduler thread */ 02804 if (netthreadid != AST_PTHREADT_NULL) 02805 pthread_kill(netthreadid, SIGURG); 02806 signal_condition(&sched_lock, &sched_cond); 02807 return 0; 02808 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 6650 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
06651 { 06652 /* Drop when trunk is about 5 seconds idle */ 06653 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 06654 return 1; 06655 return 0; 06656 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 4162 of file chan_iax2.c.
References iax2_trunk_peer::addr, chan_iax2_pvt::addr, iax_frame::af, ast_inet_ntoa(), ast_log(), ast_mutex_unlock(), ast_realloc, ast_test_flag, ast_iax2_meta_trunk_entry::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, iax2_trunk_peer::calls, DEFAULT_TRUNKDATA, f, find_tpeer(), globalflags, IAX2_TRUNK_PREFACE, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, MAX_TRUNKDATA, ast_iax2_meta_trunk_mini::mini, option_debug, chan_iax2_pvt::sockfd, iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdataalloc, iax2_trunk_peer::trunkdatalen, iax_frame::ts, and ast_iax2_mini_hdr::ts.
Referenced by iax2_send().
04163 { 04164 struct ast_frame *f; 04165 struct iax2_trunk_peer *tpeer; 04166 void *tmp, *ptr; 04167 struct ast_iax2_meta_trunk_entry *met; 04168 struct ast_iax2_meta_trunk_mini *mtm; 04169 04170 f = &fr->af; 04171 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 04172 if (tpeer) { 04173 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 04174 /* Need to reallocate space */ 04175 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) { 04176 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 04177 ast_mutex_unlock(&tpeer->lock); 04178 return -1; 04179 } 04180 04181 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 04182 tpeer->trunkdata = tmp; 04183 if (option_debug) 04184 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); 04185 } else { 04186 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)); 04187 ast_mutex_unlock(&tpeer->lock); 04188 return -1; 04189 } 04190 } 04191 04192 /* Append to meta frame */ 04193 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 04194 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 04195 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 04196 mtm->len = htons(f->datalen); 04197 mtm->mini.callno = htons(pvt->callno); 04198 mtm->mini.ts = htons(0xffff & fr->ts); 04199 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 04200 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 04201 } else { 04202 met = (struct ast_iax2_meta_trunk_entry *)ptr; 04203 /* Store call number and length in meta header */ 04204 met->callno = htons(pvt->callno); 04205 met->len = htons(f->datalen); 04206 /* Advance pointers/decrease length past trunk entry header */ 04207 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 04208 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 04209 } 04210 /* Copy actual trunk data */ 04211 memcpy(ptr, f->data, f->datalen); 04212 tpeer->trunkdatalen += f->datalen; 04213 04214 tpeer->calls++; 04215 ast_mutex_unlock(&tpeer->lock); 04216 } 04217 return 0; 04218 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 6567 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, iaxs, and send_command_immediate().
Referenced by socket_process().
06568 { 06569 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 06570 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 5105 of file chan_iax2.c.
References AST_FRAME_NULL, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, iax2_registry::callno, errno, f, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, iaxsl, option_debug, PTR_TO_CALLNO, and ast_channel::tech_pvt.
05106 { 05107 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05108 int res = -1; 05109 ast_mutex_lock(&iaxsl[callno]); 05110 if (iaxs[callno]) { 05111 /* If there's an outstanding error, return failure now */ 05112 if (!iaxs[callno]->error) { 05113 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 05114 res = 0; 05115 /* Don't waste bandwidth sending null frames */ 05116 else if (f->frametype == AST_FRAME_NULL) 05117 res = 0; 05118 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 05119 res = 0; 05120 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 05121 res = 0; 05122 else 05123 /* Simple, just queue for transmission */ 05124 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 05125 } else { 05126 if (option_debug) 05127 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); 05128 } 05129 } 05130 /* If it's already gone, just return */ 05131 ast_mutex_unlock(&iaxsl[callno]); 05132 return res; 05133 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 1962 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().
01963 { 01964 int res = 0; 01965 struct iax_firmware *cur; 01966 if (!ast_strlen_zero(dev)) { 01967 ast_mutex_lock(&waresl.lock); 01968 cur = waresl.wares; 01969 while(cur) { 01970 if (!strcmp(dev, (char *)cur->fwh->devname)) { 01971 res = ntohs(cur->fwh->version); 01972 break; 01973 } 01974 cur = cur->next; 01975 } 01976 ast_mutex_unlock(&waresl.lock); 01977 } 01978 return res; 01979 }
static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 763 of file chan_iax2.c.
References ast_verbose().
Referenced by load_module().
00764 { 00765 if (iaxdebug) 00766 ast_verbose("%s", data); 00767 }
static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 769 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
00770 { 00771 ast_log(LOG_WARNING, "%s", data); 00772 }
static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
const unsigned char * | dev, | |||
unsigned int | desc | |||
) | [static] |
Definition at line 1981 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().
01982 { 01983 int res = -1; 01984 unsigned int bs = desc & 0xff; 01985 unsigned int start = (desc >> 8) & 0xffffff; 01986 unsigned int bytes; 01987 struct iax_firmware *cur; 01988 if (!ast_strlen_zero((char *)dev) && bs) { 01989 start *= bs; 01990 ast_mutex_lock(&waresl.lock); 01991 cur = waresl.wares; 01992 while(cur) { 01993 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) { 01994 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 01995 if (start < ntohl(cur->fwh->datalen)) { 01996 bytes = ntohl(cur->fwh->datalen) - start; 01997 if (bytes > bs) 01998 bytes = bs; 01999 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 02000 } else { 02001 bytes = 0; 02002 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 02003 } 02004 if (bytes == bs) 02005 res = 0; 02006 else 02007 res = 1; 02008 break; 02009 } 02010 cur = cur->next; 02011 } 02012 ast_mutex_unlock(&waresl.lock); 02013 } 02014 return res; 02015 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2 | |||
) | [static] |
Definition at line 6838 of file chan_iax2.c.
References ast_channel::accountcode, ast_channel::amaflags, ast_calloc, ast_channel_alloc(), ast_channel_masquerade(), ast_copy_string(), 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::name, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat.
Referenced by socket_process().
06839 { 06840 struct iax_dual *d; 06841 struct ast_channel *chan1m, *chan2m; 06842 pthread_t th; 06843 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 06844 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name); 06845 if (chan2m && chan1m) { 06846 /* Make formats okay */ 06847 chan1m->readformat = chan1->readformat; 06848 chan1m->writeformat = chan1->writeformat; 06849 ast_channel_masquerade(chan1m, chan1); 06850 /* Setup the extensions and such */ 06851 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 06852 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 06853 chan1m->priority = chan1->priority; 06854 06855 /* We make a clone of the peer channel too, so we can play 06856 back the announcement */ 06857 /* Make formats okay */ 06858 chan2m->readformat = chan2->readformat; 06859 chan2m->writeformat = chan2->writeformat; 06860 ast_channel_masquerade(chan2m, chan2); 06861 /* Setup the extensions and such */ 06862 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 06863 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 06864 chan2m->priority = chan2->priority; 06865 if (ast_do_masquerade(chan2m)) { 06866 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 06867 ast_hangup(chan2m); 06868 return -1; 06869 } 06870 } else { 06871 if (chan1m) 06872 ast_hangup(chan1m); 06873 if (chan2m) 06874 ast_hangup(chan2m); 06875 return -1; 06876 } 06877 if ((d = ast_calloc(1, sizeof(*d)))) { 06878 pthread_attr_t attr; 06879 06880 pthread_attr_init(&attr); 06881 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06882 06883 d->chan1 = chan1m; 06884 d->chan2 = chan2m; 06885 if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) { 06886 pthread_attr_destroy(&attr); 06887 return 0; 06888 } 06889 pthread_attr_destroy(&attr); 06890 free(d); 06891 } 06892 return -1; 06893 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 6818 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().
06819 { 06820 struct ast_channel *chan1, *chan2; 06821 struct iax_dual *d; 06822 struct ast_frame *f; 06823 int ext; 06824 int res; 06825 d = stuff; 06826 chan1 = d->chan1; 06827 chan2 = d->chan2; 06828 free(d); 06829 f = ast_read(chan1); 06830 if (f) 06831 ast_frfree(f); 06832 res = ast_park_call(chan1, chan2, 0, &ext); 06833 ast_hangup(chan2); 06834 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 06835 return NULL; 06836 }
Definition at line 1437 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().
01438 { 01439 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01440 if (new) { 01441 size_t afdatalen = new->afdatalen; 01442 memcpy(new, fr, sizeof(*new)); 01443 iax_frame_wrap(new, &fr->af); 01444 new->afdatalen = afdatalen; 01445 new->data = NULL; 01446 new->datalen = 0; 01447 new->direction = DIRECTION_INGRESS; 01448 new->retrans = -1; 01449 } 01450 return new; 01451 }
static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 893 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().
00894 { 00895 if (thread->type == IAX_TYPE_DYNAMIC) { 00896 AST_LIST_LOCK(&dynamic_list); 00897 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 00898 AST_LIST_UNLOCK(&dynamic_list); 00899 } else { 00900 AST_LIST_LOCK(&idle_list); 00901 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 00902 AST_LIST_UNLOCK(&idle_list); 00903 } 00904 00905 return; 00906 }
static void jb_debug_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 798 of file chan_iax2.c.
References ast_verbose().
Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug().
00799 { 00800 va_list args; 00801 char buf[1024]; 00802 00803 va_start(args, fmt); 00804 vsnprintf(buf, 1024, fmt, args); 00805 va_end(args); 00806 00807 ast_verbose("%s", buf); 00808 }
static void jb_error_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 774 of file chan_iax2.c.
References ast_log(), and LOG_ERROR.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00775 { 00776 va_list args; 00777 char buf[1024]; 00778 00779 va_start(args, fmt); 00780 vsnprintf(buf, 1024, fmt, args); 00781 va_end(args); 00782 00783 ast_log(LOG_ERROR, "%s", buf); 00784 }
static void jb_warning_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 786 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00787 { 00788 va_list args; 00789 char buf[1024]; 00790 00791 va_start(args, fmt); 00792 vsnprintf(buf, 1024, fmt, args); 00793 va_end(args); 00794 00795 ast_log(LOG_WARNING, "%s", buf); 00796 }
static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 11219 of file chan_iax2.c.
References __unload_module(), ao2_callback(), ao2_container_alloc(), ao2_ref(), ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple(), ast_cond_init(), ast_custom_function_register(), AST_LIST_HEAD_INIT, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_register, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, ast_mutex_init(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_register_application(), ast_register_switch(), ast_verbose(), cli_iax2, config, DAHDI_FILE_PSEUDO, DAHDI_FILE_TIMER, iax2_registry::entry, errno, iax2_do_register(), iax2_poke_peer_cb(), iax2_prov_app(), iax2_switch, iax2_tech, iax_debug_output(), iax_error_output(), IAX_MAX_CALLS, iax_peercallno_pvts, iax_provision_reload(), iax_set_error(), iax_set_output(), iaxpeer_function, iaxq, iaxs, iaxsl, io, io_context_create(), jb_error_output(), jb_setoutput(), jb_warning_output(), ast_firmware_list::lock, LOG_ERROR, LOG_WARNING, manager_iax2_show_netstats(), manager_iax2_show_peers(), MAX_PEER_BUCKETS, MAX_USER_BUCKETS, netsock, option_verbose, outsock, peer_cmp_cb(), peer_hash_cb(), peer_set_sock_cb(), pvt_cmp_cb(), pvt_hash_cb(), ast_iax2_queue::queue, reload_firmware(), sched, sched_context_create(), set_config(), start_network_thread(), user_cmp_cb(), user_hash_cb(), VERBOSE_PREFIX_2, and waresl.
11220 { 11221 char *config = "iax.conf"; 11222 int res = 0; 11223 int x; 11224 struct iax2_registry *reg = NULL; 11225 11226 peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb); 11227 if (!peers) 11228 return AST_MODULE_LOAD_FAILURE; 11229 users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb); 11230 if (!users) { 11231 ao2_ref(peers, -1); 11232 return AST_MODULE_LOAD_FAILURE; 11233 } 11234 iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb); 11235 if (!iax_peercallno_pvts) { 11236 ao2_ref(peers, -1); 11237 ao2_ref(users, -1); 11238 return AST_MODULE_LOAD_FAILURE; 11239 } 11240 11241 ast_custom_function_register(&iaxpeer_function); 11242 11243 iax_set_output(iax_debug_output); 11244 iax_set_error(iax_error_output); 11245 jb_setoutput(jb_error_output, jb_warning_output, NULL); 11246 11247 #ifdef HAVE_DAHDI 11248 #ifdef DAHDI_TIMERACK 11249 timingfd = open(DAHDI_FILE_TIMER, O_RDWR); 11250 if (timingfd < 0) 11251 #endif 11252 timingfd = open(DAHDI_FILE_PSEUDO, O_RDWR); 11253 if (timingfd < 0) 11254 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno)); 11255 #endif 11256 11257 memset(iaxs, 0, sizeof(iaxs)); 11258 11259 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 11260 ast_mutex_init(&iaxsl[x]); 11261 } 11262 11263 ast_cond_init(&sched_cond, NULL); 11264 11265 io = io_context_create(); 11266 sched = sched_context_create(); 11267 11268 if (!io || !sched) { 11269 ast_log(LOG_ERROR, "Out of memory\n"); 11270 return -1; 11271 } 11272 11273 netsock = ast_netsock_list_alloc(); 11274 if (!netsock) { 11275 ast_log(LOG_ERROR, "Could not allocate netsock list.\n"); 11276 return -1; 11277 } 11278 ast_netsock_init(netsock); 11279 11280 outsock = ast_netsock_list_alloc(); 11281 if (!outsock) { 11282 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 11283 return -1; 11284 } 11285 ast_netsock_init(outsock); 11286 11287 ast_mutex_init(&waresl.lock); 11288 11289 AST_LIST_HEAD_INIT(&iaxq.queue); 11290 11291 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 11292 11293 ast_register_application(papp, iax2_prov_app, psyn, pdescrip); 11294 11295 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" ); 11296 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" ); 11297 11298 if(set_config(config, 0) == -1) 11299 return AST_MODULE_LOAD_DECLINE; 11300 11301 if (ast_channel_register(&iax2_tech)) { 11302 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 11303 __unload_module(); 11304 return -1; 11305 } 11306 11307 if (ast_register_switch(&iax2_switch)) 11308 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 11309 11310 res = start_network_thread(); 11311 if (!res) { 11312 if (option_verbose > 1) 11313 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n"); 11314 } else { 11315 ast_log(LOG_ERROR, "Unable to start network thread\n"); 11316 ast_netsock_release(netsock); 11317 ast_netsock_release(outsock); 11318 } 11319 11320 AST_LIST_LOCK(®istrations); 11321 AST_LIST_TRAVERSE(®istrations, reg, entry) 11322 iax2_do_register(reg); 11323 AST_LIST_UNLOCK(®istrations); 11324 11325 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 11326 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 11327 11328 reload_firmware(0); 11329 iax_provision_reload(); 11330 return res; 11331 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3582 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), DEADLOCK_AVOIDANCE, and iaxsl.
Referenced by iax2_bridge().
03583 { 03584 ast_mutex_lock(&iaxsl[callno0]); 03585 while (ast_mutex_trylock(&iaxsl[callno1])) { 03586 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 03587 } 03588 }
static int make_trunk | ( | unsigned short | callno, | |
int | locked | |||
) | [static] |
Definition at line 1491 of file chan_iax2.c.
References ARRAY_LEN, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_SCHED_DEL, iax2_sched_add(), LOG_DEBUG, LOG_WARNING, MIN_REUSE_TIME, option_debug, sched, send_lagrq(), send_ping(), TRUNK_CALL_START, update_max_nontrunk(), and update_max_trunk().
Referenced by iax2_request(), and socket_process().
01492 { 01493 int x; 01494 int res= 0; 01495 struct timeval now; 01496 if (iaxs[callno]->oseqno) { 01497 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 01498 return -1; 01499 } 01500 if (callno & TRUNK_CALL_START) { 01501 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01502 return -1; 01503 } 01504 gettimeofday(&now, NULL); 01505 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 01506 ast_mutex_lock(&iaxsl[x]); 01507 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01508 /* Update the two timers that should have been started */ 01509 /*! 01510 * \note We delete these before switching the slot, because if 01511 * they fire in the meantime, they will generate a warning. 01512 */ 01513 AST_SCHED_DEL(sched, iaxs[callno]->pingid); 01514 AST_SCHED_DEL(sched, iaxs[callno]->lagid); 01515 iaxs[x] = iaxs[callno]; 01516 iaxs[x]->callno = x; 01517 iaxs[callno] = NULL; 01518 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01519 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01520 if (locked) 01521 ast_mutex_unlock(&iaxsl[callno]); 01522 res = x; 01523 if (!locked) 01524 ast_mutex_unlock(&iaxsl[x]); 01525 break; 01526 } 01527 ast_mutex_unlock(&iaxsl[x]); 01528 } 01529 if (x >= ARRAY_LEN(iaxs) - 1) { 01530 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01531 return -1; 01532 } 01533 if (option_debug) 01534 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x); 01535 /* We move this call from a non-trunked to a trunked call */ 01536 update_max_trunk(); 01537 update_max_nontrunk(); 01538 return res; 01539 }
static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4819 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), RESULT_SUCCESS, and s.
Referenced by load_module().
04820 { 04821 ast_cli_netstats(s, -1, 0); 04822 astman_append(s, "\r\n"); 04823 return RESULT_SUCCESS; 04824 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4852 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), and s.
Referenced by load_module().
04853 { 04854 char *a[] = { "iax2", "show", "users" }; 04855 int ret; 04856 const char *id = astman_get_header(m,"ActionID"); 04857 04858 if (!ast_strlen_zero(id)) 04859 astman_append(s, "ActionID: %s\r\n",id); 04860 ret = __iax2_show_peers(1, -1, s, 3, a ); 04861 astman_append(s, "\r\n\r\n" ); 04862 return ret; 04863 } /* /JDG */
static int match | ( | struct sockaddr_in * | sin, | |
unsigned short | callno, | |||
unsigned short | dcallno, | |||
struct chan_iax2_pvt * | cur, | |||
int | check_dcallno | |||
) | [static] |
Definition at line 1457 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::callno, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, chan_iax2_pvt::transfercallno, and chan_iax2_pvt::transferring.
Referenced by __find_callno(), ao2_callback(), ast_parse_device_state(), check_blacklist(), find_command(), get_sip_pvt_byid_locked(), handle_updates(), pbx_find_extension(), pvt_cmp_cb(), realtime_switch_common(), and softhangup_exec().
01458 { 01459 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01460 (cur->addr.sin_port == sin->sin_port)) { 01461 /* This is the main host */ 01462 if ( (cur->peercallno == 0 || cur->peercallno == callno) && 01463 (check_dcallno ? dcallno == cur->callno : 1) ) { 01464 /* That's us. Be sure we keep track of the peer call number */ 01465 return 1; 01466 } 01467 } 01468 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01469 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01470 /* We're transferring */ 01471 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 01472 return 1; 01473 } 01474 return 0; 01475 }
static void memcpy_decrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 4226 of file chan_iax2.c.
References aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
04227 { 04228 #if 0 04229 /* Debug with "fake encryption" */ 04230 int x; 04231 if (len % 16) 04232 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 04233 for (x=0;x<len;x++) 04234 dst[x] = src[x] ^ 0xff; 04235 #else 04236 unsigned char lastblock[16] = { 0 }; 04237 int x; 04238 while(len > 0) { 04239 aes_decrypt(src, dst, dcx); 04240 for (x=0;x<16;x++) 04241 dst[x] ^= lastblock[x]; 04242 memcpy(lastblock, src, sizeof(lastblock)); 04243 dst += 16; 04244 src += 16; 04245 len -= 16; 04246 } 04247 #endif 04248 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_encrypt_ctx * | ecx | |||
) | [static] |
Definition at line 4250 of file chan_iax2.c.
References aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
04251 { 04252 #if 0 04253 /* Debug with "fake encryption" */ 04254 int x; 04255 if (len % 16) 04256 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 04257 for (x=0;x<len;x++) 04258 dst[x] = src[x] ^ 0xff; 04259 #else 04260 unsigned char curblock[16] = { 0 }; 04261 int x; 04262 while(len > 0) { 04263 for (x=0;x<16;x++) 04264 curblock[x] ^= src[x]; 04265 aes_encrypt(curblock, dst, ecx); 04266 memcpy(curblock, dst, sizeof(curblock)); 04267 dst += 16; 04268 src += 16; 04269 len -= 16; 04270 } 04271 #endif 04272 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 5427 of file chan_iax2.c.
References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.
Referenced by authenticate_reply(), and socket_process().
05428 { 05429 /* Select exactly one common encryption if there are any */ 05430 p->encmethods &= enc; 05431 if (p->encmethods) { 05432 if (p->encmethods & IAX_ENCRYPT_AES128) 05433 p->encmethods = IAX_ENCRYPT_AES128; 05434 else 05435 p->encmethods = 0; 05436 } 05437 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 9191 of file chan_iax2.c.
References ast_io_add(), AST_IO_IN, AST_IO_PRI, ast_io_wait(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), attempt_transmit(), ast_iax2_queue::count, f, iax2_sched_add(), iax_frame_free(), iaxq, iaxs, iaxsl, io, iax_frame::list, option_debug, ast_iax2_queue::queue, sched, send_packet(), and timing_read().
Referenced by start_network_thread().
09192 { 09193 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 09194 from the network, and queue them for delivery to the channels */ 09195 int res, count, wakeup; 09196 struct iax_frame *f; 09197 09198 if (timingfd > -1) 09199 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL); 09200 09201 for(;;) { 09202 pthread_testcancel(); 09203 09204 /* Go through the queue, sending messages which have not yet been 09205 sent, and scheduling retransmissions if appropriate */ 09206 AST_LIST_LOCK(&iaxq.queue); 09207 count = 0; 09208 wakeup = -1; 09209 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) { 09210 if (f->sentyet) 09211 continue; 09212 09213 /* Try to lock the pvt, if we can't... don't fret - defer it till later */ 09214 if (ast_mutex_trylock(&iaxsl[f->callno])) { 09215 wakeup = 1; 09216 continue; 09217 } 09218 09219 f->sentyet++; 09220 09221 if (iaxs[f->callno]) { 09222 send_packet(f); 09223 count++; 09224 } 09225 09226 ast_mutex_unlock(&iaxsl[f->callno]); 09227 09228 if (f->retries < 0) { 09229 /* This is not supposed to be retransmitted */ 09230 AST_LIST_REMOVE_CURRENT(&iaxq.queue, list); 09231 iaxq.count--; 09232 /* Free the iax frame */ 09233 iax_frame_free(f); 09234 } else { 09235 /* We need reliable delivery. Schedule a retransmission */ 09236 f->retries++; 09237 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 09238 } 09239 } 09240 AST_LIST_TRAVERSE_SAFE_END 09241 AST_LIST_UNLOCK(&iaxq.queue); 09242 09243 pthread_testcancel(); 09244 09245 if (option_debug && count >= 20) 09246 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 09247 09248 /* Now do the IO, and run scheduled tasks */ 09249 res = ast_io_wait(io, wakeup); 09250 if (res >= 0) { 09251 if (option_debug && res >= 20) 09252 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 09253 } 09254 } 09255 return NULL; 09256 }
static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
const char * | host | |||
) | [static] |
Definition at line 1398 of file chan_iax2.c.
References ao2_alloc(), ao2_ref(), ast_string_field_init, ast_string_field_set, exten, jb_new(), jb_setconf(), jb_conf::max_contig_interp, jb_conf::max_jitterbuf, prefs, pvt_destructor(), and jb_conf::resync_threshold.
Referenced by __find_callno().
01399 { 01400 struct chan_iax2_pvt *tmp; 01401 jb_conf jbconf; 01402 01403 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) { 01404 return NULL; 01405 } 01406 01407 if (ast_string_field_init(tmp, 32)) { 01408 ao2_ref(tmp, -1); 01409 tmp = NULL; 01410 return NULL; 01411 } 01412 01413 tmp->prefs = prefs; 01414 tmp->callno = 0; 01415 tmp->peercallno = 0; 01416 tmp->transfercallno = 0; 01417 tmp->bridgecallno = 0; 01418 tmp->pingid = -1; 01419 tmp->lagid = -1; 01420 tmp->autoid = -1; 01421 tmp->authid = -1; 01422 tmp->initid = -1; 01423 01424 ast_string_field_set(tmp,exten, "s"); 01425 ast_string_field_set(tmp,host, host); 01426 01427 tmp->jb = jb_new(); 01428 tmp->jbid = -1; 01429 jbconf.max_jitterbuf = maxjitterbuffer; 01430 jbconf.resync_threshold = resyncthreshold; 01431 jbconf.max_contig_interp = maxjitterinterps; 01432 jb_setconf(tmp->jb,&jbconf); 01433 01434 return tmp; 01435 }
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 3253 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, and parsed_dial_string::username.
Referenced by cache_get_callno_locked(), iax2_call(), iax2_devicestate(), and iax2_request().
03254 { 03255 if (ast_strlen_zero(data)) 03256 return; 03257 03258 pds->peer = strsep(&data, "/"); 03259 pds->exten = strsep(&data, "/"); 03260 pds->options = data; 03261 03262 if (pds->exten) { 03263 data = pds->exten; 03264 pds->exten = strsep(&data, "@"); 03265 pds->context = data; 03266 } 03267 03268 if (strchr(pds->peer, '@')) { 03269 data = pds->peer; 03270 pds->username = strsep(&data, "@"); 03271 pds->peer = data; 03272 } 03273 03274 if (pds->username) { 03275 data = pds->username; 03276 pds->username = strsep(&data, ":"); 03277 pds->password = data; 03278 } 03279 03280 data = pds->peer; 03281 pds->peer = strsep(&data, ":"); 03282 pds->port = data; 03283 03284 /* check for a key name wrapped in [] in the secret position, if found, 03285 move it to the key field instead 03286 */ 03287 if (pds->password && (pds->password[0] == '[')) { 03288 pds->key = ast_strip_quoted(pds->password, "[", "]"); 03289 pds->password = NULL; 03290 } 03291 }
static int peer_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1120 of file chan_iax2.c.
References iax2_peer::name.
Referenced by load_module().
01121 { 01122 struct iax2_peer *peer = obj, *peer2 = arg; 01123 01124 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0; 01125 }
static int peer_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9881 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
09882 { 09883 struct iax2_peer *peer = obj; 09884 09885 ast_set_flag(peer, IAX_DELME); 09886 09887 return 0; 09888 }
static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 9414 of file chan_iax2.c.
References ast_dnsmgr_release(), ast_free_ha(), ast_mutex_lock(), ast_mutex_unlock(), ast_string_field_free_memory, iax2_peer::callno, iax2_peer::dnsmgr, iax2_peer::ha, iax2_destroy(), iaxsl, and register_peer_exten().
Referenced by build_peer().
09415 { 09416 struct iax2_peer *peer = obj; 09417 int callno = peer->callno; 09418 09419 ast_free_ha(peer->ha); 09420 09421 if (callno > 0) { 09422 ast_mutex_lock(&iaxsl[callno]); 09423 iax2_destroy(callno); 09424 ast_mutex_unlock(&iaxsl[callno]); 09425 } 09426 09427 register_peer_exten(peer, 0); 09428 09429 if (peer->dnsmgr) 09430 ast_dnsmgr_release(peer->dnsmgr); 09431 09432 ast_string_field_free_memory(peer); 09433 }
static int peer_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1110 of file chan_iax2.c.
References ast_str_hash(), and iax2_peer::name.
Referenced by load_module().
01111 { 01112 const struct iax2_peer *peer = obj; 01113 01114 return ast_str_hash(peer->name); 01115 }
Definition at line 1167 of file chan_iax2.c.
References ao2_ref().
Referenced by __iax2_poke_noanswer(), iax2_poke_peer(), iax2_prune_realtime(), reg_source_db(), socket_process(), and update_registry().
01168 { 01169 ao2_ref(peer, +1); 01170 return peer; 01171 }
static int peer_set_sock_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11190 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
11191 { 11192 struct iax2_peer *peer = obj; 11193 11194 if (peer->sockfd < 0) 11195 peer->sockfd = defaultsockfd; 11196 11197 return 0; 11198 }
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 9341 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, iax2_peer::name, netsock, option_debug, outsock, socket_read(), and iax2_peer::sockfd.
Referenced by build_peer().
09342 { 09343 struct sockaddr_in sin; 09344 int nonlocal = 1; 09345 int port = IAX_DEFAULT_PORTNO; 09346 int sockfd = defaultsockfd; 09347 char *tmp; 09348 char *addr; 09349 char *portstr; 09350 09351 if (!(tmp = ast_strdupa(srcaddr))) 09352 return -1; 09353 09354 addr = strsep(&tmp, ":"); 09355 portstr = tmp; 09356 09357 if (portstr) { 09358 port = atoi(portstr); 09359 if (port < 1) 09360 port = IAX_DEFAULT_PORTNO; 09361 } 09362 09363 if (!ast_get_ip(&sin, addr)) { 09364 struct ast_netsock *sock; 09365 int res; 09366 09367 sin.sin_port = 0; 09368 sin.sin_family = AF_INET; 09369 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 09370 if (res == 0) { 09371 /* ip address valid. */ 09372 sin.sin_port = htons(port); 09373 if (!(sock = ast_netsock_find(netsock, &sin))) 09374 sock = ast_netsock_find(outsock, &sin); 09375 if (sock) { 09376 sockfd = ast_netsock_sockfd(sock); 09377 nonlocal = 0; 09378 } else { 09379 unsigned int orig_saddr = sin.sin_addr.s_addr; 09380 /* INADDR_ANY matches anyway! */ 09381 sin.sin_addr.s_addr = INADDR_ANY; 09382 if (ast_netsock_find(netsock, &sin)) { 09383 sin.sin_addr.s_addr = orig_saddr; 09384 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL); 09385 if (sock) { 09386 sockfd = ast_netsock_sockfd(sock); 09387 ast_netsock_unref(sock); 09388 nonlocal = 0; 09389 } else { 09390 nonlocal = 2; 09391 } 09392 } 09393 } 09394 } 09395 } 09396 09397 peer->sockfd = sockfd; 09398 09399 if (nonlocal == 1) { 09400 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 09401 srcaddr, peer->name); 09402 return -1; 09403 } else if (nonlocal == 2) { 09404 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 09405 srcaddr, peer->name); 09406 return -1; 09407 } else { 09408 if (option_debug) 09409 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 09410 return 0; 09411 } 09412 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 2374 of file chan_iax2.c.
References ast_copy_string(), 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().
02375 { 02376 int res = 0; 02377 if (peer->maxms) { 02378 if (peer->lastms < 0) { 02379 ast_copy_string(status, "UNREACHABLE", statuslen); 02380 } else if (peer->lastms > peer->maxms) { 02381 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 02382 res = 1; 02383 } else if (peer->lastms) { 02384 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 02385 res = 1; 02386 } else { 02387 ast_copy_string(status, "UNKNOWN", statuslen); 02388 } 02389 } else { 02390 ast_copy_string(status, "Unmonitored", statuslen); 02391 res = -1; 02392 } 02393 return res; 02394 }
Definition at line 1173 of file chan_iax2.c.
References ao2_ref().
Referenced by __expire_registry(), __iax2_poke_noanswer(), __iax2_poke_peer_s(), __iax2_show_peers(), authenticate_reply(), build_peer(), complete_iax2_show_peer(), create_addr(), function_iaxpeer(), iax2_devicestate(), iax2_getpeername(), iax2_getpeertrunk(), iax2_poke_noanswer(), iax2_poke_peer(), iax2_prune_realtime(), iax2_show_peer(), poke_all_peers(), prune_peers(), reg_source_db(), registry_authrequest(), set_config(), socket_process(), unlink_peer(), and update_registry().
01174 { 01175 ao2_ref(peer, -1); 01176 return NULL; 01177 }
static void poke_all_peers | ( | void | ) | [static] |
Definition at line 10343 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), iax2_poke_peer(), and peer_unref().
Referenced by reload_config().
10344 { 10345 struct ao2_iterator i; 10346 struct iax2_peer *peer; 10347 10348 i = ao2_iterator_init(peers, 0); 10349 while ((peer = ao2_iterator_next(&i))) { 10350 iax2_poke_peer(peer, 0); 10351 peer_unref(peer); 10352 } 10353 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 9940 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_test_flag, IAX_DELME, peer_unref(), and unlink_peer().
09941 { 09942 struct iax2_peer *peer; 09943 struct ao2_iterator i; 09944 09945 i = ao2_iterator_init(peers, 0); 09946 while ((peer = ao2_iterator_next(&i))) { 09947 if (ast_test_flag(peer, IAX_DELME)) 09948 unlink_peer(peer); 09949 peer_unref(peer); 09950 } 09951 }
static void prune_users | ( | void | ) | [static] |
Definition at line 9926 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ao2_unlink(), ast_test_flag, IAX_DELME, and user_unref().
Referenced by reload_config().
09927 { 09928 struct iax2_user *user; 09929 struct ao2_iterator i; 09930 09931 i = ao2_iterator_init(users, 0); 09932 while ((user = ao2_iterator_next(&i))) { 09933 if (ast_test_flag(user, IAX_DELME)) 09934 ao2_unlink(users, user); 09935 user_unref(user); 09936 } 09937 }
static int pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11207 of file chan_iax2.c.
References chan_iax2_pvt::frames_received, and match().
Referenced by load_module().
11208 { 11209 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 11210 11211 /* The frames_received field is used to hold whether we're matching 11212 * against a full frame or not ... */ 11213 11214 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 11215 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 11216 }
static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1359 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_set_flag, ast_string_field_free_memory, ast_variables_destroy(), iax2_registry::callno, chan_iax2_pvt::callno, iax_frame::callno, jb_frame::data, iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, iaxq, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, iax_frame::list, chan_iax2_pvt::owner, ast_iax2_queue::queue, chan_iax2_pvt::reg, iax_frame::retries, and chan_iax2_pvt::vars.
Referenced by new_iax().
01360 { 01361 struct chan_iax2_pvt *pvt = obj; 01362 struct iax_frame *cur = NULL; 01363 01364 iax2_destroy_helper(pvt); 01365 01366 /* Already gone */ 01367 ast_set_flag(pvt, IAX_ALREADYGONE); 01368 01369 AST_LIST_LOCK(&iaxq.queue); 01370 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 01371 /* Cancel any pending transmissions */ 01372 if (cur->callno == pvt->callno) { 01373 cur->retries = -1; 01374 } 01375 } 01376 AST_LIST_UNLOCK(&iaxq.queue); 01377 01378 if (pvt->reg) { 01379 pvt->reg->callno = 0; 01380 } 01381 01382 if (!pvt->owner) { 01383 jb_frame frame; 01384 if (pvt->vars) { 01385 ast_variables_destroy(pvt->vars); 01386 pvt->vars = NULL; 01387 } 01388 01389 while (jb_getall(pvt->jb, &frame) == JB_OK) { 01390 iax2_frame_free(frame.data); 01391 } 01392 01393 jb_destroy(pvt->jb); 01394 ast_string_field_free_memory(pvt); 01395 } 01396 }
static int pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 11200 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
Referenced by load_module().
11201 { 11202 const struct chan_iax2_pvt *pvt = obj; 11203 11204 return pvt->peercallno; 11205 }
static int raw_hangup | ( | struct sockaddr_in * | sin, | |
unsigned short | src, | |||
unsigned short | dst, | |||
int | sockfd | |||
) | [static] |
Definition at line 5409 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().
05410 { 05411 struct ast_iax2_full_hdr fh; 05412 fh.scallno = htons(src | IAX_FLAG_FULL); 05413 fh.dcallno = htons(dst); 05414 fh.ts = 0; 05415 fh.oseqno = 0; 05416 fh.iseqno = 0; 05417 fh.type = AST_FRAME_IAX; 05418 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 05419 if (iaxdebug) 05420 iax_showframe(NULL, &fh, 0, sin, 0); 05421 if (option_debug) 05422 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n", 05423 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 05424 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 05425 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 2855 of file chan_iax2.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), hp, ast_variable::name, ast_variable::next, ast_variable::value, and var.
02856 { 02857 struct ast_variable *var = NULL; 02858 struct ast_variable *tmp; 02859 struct iax2_peer *peer=NULL; 02860 time_t regseconds = 0, nowtime; 02861 int dynamic=0; 02862 02863 if (peername) { 02864 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL); 02865 if (!var && sin) 02866 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02867 } else if (sin) { 02868 char porta[25]; 02869 sprintf(porta, "%d", ntohs(sin->sin_port)); 02870 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02871 if (var) { 02872 /* We'll need the peer name in order to build the structure! */ 02873 for (tmp = var; tmp; tmp = tmp->next) { 02874 if (!strcasecmp(tmp->name, "name")) 02875 peername = tmp->value; 02876 } 02877 } 02878 } 02879 if (!var && peername) { /* Last ditch effort */ 02880 var = ast_load_realtime("iaxpeers", "name", peername, NULL); 02881 /*!\note 02882 * If this one loaded something, then we need to ensure that the host 02883 * field matched. The only reason why we can't have this as a criteria 02884 * is because we only have the IP address and the host field might be 02885 * set as a name (and the reverse PTR might not match). 02886 */ 02887 if (var && sin) { 02888 for (tmp = var; tmp; tmp = tmp->next) { 02889 if (!strcasecmp(tmp->name, "host")) { 02890 struct ast_hostent ahp; 02891 struct hostent *hp; 02892 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02893 /* No match */ 02894 ast_variables_destroy(var); 02895 var = NULL; 02896 } 02897 break; 02898 } 02899 } 02900 } 02901 } 02902 if (!var) 02903 return NULL; 02904 02905 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 02906 02907 if (!peer) { 02908 ast_variables_destroy(var); 02909 return NULL; 02910 } 02911 02912 for (tmp = var; tmp; tmp = tmp->next) { 02913 /* Make sure it's not a user only... */ 02914 if (!strcasecmp(tmp->name, "type")) { 02915 if (strcasecmp(tmp->value, "friend") && 02916 strcasecmp(tmp->value, "peer")) { 02917 /* Whoops, we weren't supposed to exist! */ 02918 peer = peer_unref(peer); 02919 break; 02920 } 02921 } else if (!strcasecmp(tmp->name, "regseconds")) { 02922 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 02923 } else if (!strcasecmp(tmp->name, "ipaddr")) { 02924 inet_aton(tmp->value, &(peer->addr.sin_addr)); 02925 } else if (!strcasecmp(tmp->name, "port")) { 02926 peer->addr.sin_port = htons(atoi(tmp->value)); 02927 } else if (!strcasecmp(tmp->name, "host")) { 02928 if (!strcasecmp(tmp->value, "dynamic")) 02929 dynamic = 1; 02930 } 02931 } 02932 02933 ast_variables_destroy(var); 02934 02935 if (!peer) 02936 return NULL; 02937 02938 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02939 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 02940 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 02941 if (peer->expire > -1) { 02942 if (!ast_sched_del(sched, peer->expire)) { 02943 peer->expire = -1; 02944 peer_unref(peer); 02945 } 02946 } 02947 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 02948 if (peer->expire == -1) 02949 peer_unref(peer); 02950 } 02951 ao2_link(peers, peer); 02952 if (ast_test_flag(peer, IAX_DYNAMIC)) 02953 reg_source_db(peer); 02954 } else { 02955 ast_set_flag(peer, IAX_TEMPONLY); 02956 } 02957 02958 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 02959 time(&nowtime); 02960 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 02961 memset(&peer->addr, 0, sizeof(peer->addr)); 02962 realtime_update_peer(peer->name, &peer->addr, 0); 02963 if (option_debug) 02964 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 02965 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02966 } 02967 else { 02968 if (option_debug) 02969 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 02970 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02971 } 02972 } 02973 02974 return peer; 02975 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
time_t | regtime | |||
) | [static] |
Definition at line 3048 of file chan_iax2.c.
References ast_inet_ntoa(), and ast_update_realtime().
Referenced by __expire_registry(), update_peer(), and update_registry().
03049 { 03050 char port[10]; 03051 char regseconds[20]; 03052 03053 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 03054 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 03055 ast_update_realtime("iaxpeers", "name", peername, 03056 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 03057 "regseconds", regseconds, NULL); 03058 }
static struct iax2_user* realtime_user | ( | const char * | username, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 2977 of file chan_iax2.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), hp, ast_variable::name, ast_variable::next, ast_variable::value, and var.
02978 { 02979 struct ast_variable *var; 02980 struct ast_variable *tmp; 02981 struct iax2_user *user=NULL; 02982 02983 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL); 02984 if (!var) 02985 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02986 if (!var && sin) { 02987 char porta[6]; 02988 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 02989 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02990 if (!var) 02991 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02992 } 02993 if (!var) { /* Last ditch effort */ 02994 var = ast_load_realtime("iaxusers", "name", username, NULL); 02995 /*!\note 02996 * If this one loaded something, then we need to ensure that the host 02997 * field matched. The only reason why we can't have this as a criteria 02998 * is because we only have the IP address and the host field might be 02999 * set as a name (and the reverse PTR might not match). 03000 */ 03001 if (var) { 03002 for (tmp = var; tmp; tmp = tmp->next) { 03003 if (!strcasecmp(tmp->name, "host")) { 03004 struct ast_hostent ahp; 03005 struct hostent *hp; 03006 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 03007 /* No match */ 03008 ast_variables_destroy(var); 03009 var = NULL; 03010 } 03011 break; 03012 } 03013 } 03014 } 03015 } 03016 if (!var) 03017 return NULL; 03018 03019 tmp = var; 03020 while(tmp) { 03021 /* Make sure it's not a peer only... */ 03022 if (!strcasecmp(tmp->name, "type")) { 03023 if (strcasecmp(tmp->value, "friend") && 03024 strcasecmp(tmp->value, "user")) { 03025 return NULL; 03026 } 03027 } 03028 tmp = tmp->next; 03029 } 03030 03031 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 03032 03033 ast_variables_destroy(var); 03034 03035 if (!user) 03036 return NULL; 03037 03038 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 03039 ast_set_flag(user, IAX_RTCACHEFRIENDS); 03040 ao2_link(users, user); 03041 } else { 03042 ast_set_flag(user, IAX_TEMPONLY); 03043 } 03044 03045 return user; 03046 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 6200 of file chan_iax2.c.
References iax2_peer::addr, ast_db_get(), ast_device_state_changed(), ast_inet_ntoa(), ast_sched_del(), ast_test_flag, ast_verbose(), iax2_peer::expire, expire_registry(), iax2_peer::expiry, iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), IAX_TEMPONLY, iax2_peer::name, option_verbose, peer_ref(), peer_unref(), register_peer_exten(), sched, and VERBOSE_PREFIX_3.
Referenced by build_peer(), set_config(), and temp_peer().
06201 { 06202 char data[80]; 06203 struct in_addr in; 06204 char *c, *d; 06205 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 06206 c = strchr(data, ':'); 06207 if (c) { 06208 *c = '\0'; 06209 c++; 06210 if (inet_aton(data, &in)) { 06211 d = strchr(c, ':'); 06212 if (d) { 06213 *d = '\0'; 06214 d++; 06215 if (option_verbose > 2) 06216 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 06217 ast_inet_ntoa(in), atoi(c), atoi(d)); 06218 iax2_poke_peer(p, 0); 06219 p->expiry = atoi(d); 06220 memset(&p->addr, 0, sizeof(p->addr)); 06221 p->addr.sin_family = AF_INET; 06222 p->addr.sin_addr = in; 06223 p->addr.sin_port = htons(atoi(c)); 06224 if (p->expire > -1) { 06225 if (!ast_sched_del(sched, p->expire)) { 06226 p->expire = -1; 06227 peer_unref(p); 06228 } 06229 } 06230 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06231 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 06232 if (p->expire == -1) 06233 peer_unref(p); 06234 if (iax2_regfunk) 06235 iax2_regfunk(p->name, 1); 06236 register_peer_exten(p, 1); 06237 } 06238 06239 } 06240 } 06241 } 06242 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 6120 of file chan_iax2.c.
References ast_add_extension(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free, ast_strdup, ast_strlen_zero(), ext, iax2_peer::name, iax2_peer::regexten, and S_OR.
Referenced by __expire_registry(), expire_register(), parse_register_contact(), peer_destructor(), reg_source_db(), sip_destroy_peer(), and update_registry().
06121 { 06122 char multi[256]; 06123 char *stringp, *ext; 06124 if (!ast_strlen_zero(regcontext)) { 06125 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 06126 stringp = multi; 06127 while((ext = strsep(&stringp, "&"))) { 06128 if (onoff) { 06129 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 06130 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 06131 "Noop", ast_strdup(peer->name), ast_free, "IAX2"); 06132 } else 06133 ast_context_remove_extension(regcontext, ext, 1, NULL); 06134 } 06135 } 06136 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 5573 of file chan_iax2.c.
References iax2_peer::addr, ast_apply_ha(), ast_check_signature, ast_clear_flag, ast_copy_string(), 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(), iax2_peer::inkeys, LOG_NOTICE, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), iax2_peer::name, iax2_peer::secret, and secret.
Referenced by handle_request_register(), and socket_process().
05574 { 05575 char requeststr[256] = ""; 05576 char peer[256] = ""; 05577 char md5secret[256] = ""; 05578 char rsasecret[256] = ""; 05579 char secret[256] = ""; 05580 struct iax2_peer *p = NULL; 05581 struct ast_key *key; 05582 char *keyn; 05583 int x; 05584 int expire = 0; 05585 int res = -1; 05586 05587 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED); 05588 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 05589 if (ies->username) 05590 ast_copy_string(peer, ies->username, sizeof(peer)); 05591 if (ies->password) 05592 ast_copy_string(secret, ies->password, sizeof(secret)); 05593 if (ies->md5_result) 05594 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05595 if (ies->rsa_result) 05596 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05597 if (ies->refresh) 05598 expire = ies->refresh; 05599 05600 if (ast_strlen_zero(peer)) { 05601 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 05602 return -1; 05603 } 05604 05605 /* SLD: first call to lookup peer during registration */ 05606 ast_mutex_unlock(&iaxsl[callno]); 05607 p = find_peer(peer, 1); 05608 ast_mutex_lock(&iaxsl[callno]); 05609 if (!p || !iaxs[callno]) { 05610 if (iaxs[callno]) { 05611 ast_string_field_set(iaxs[callno], secret, "badsecret"); 05612 } 05613 if (authdebug && !p) 05614 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05615 goto return_unref; 05616 } 05617 05618 if (!ast_test_flag(p, IAX_DYNAMIC)) { 05619 if (authdebug) 05620 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05621 goto return_unref; 05622 } 05623 05624 if (!ast_apply_ha(p->ha, sin)) { 05625 if (authdebug) 05626 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05627 goto return_unref; 05628 } 05629 if (!inaddrcmp(&p->addr, sin)) 05630 ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED); 05631 ast_string_field_set(iaxs[callno], secret, p->secret); 05632 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 05633 /* Check secret against what we have on file */ 05634 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05635 if (!ast_strlen_zero(p->inkeys)) { 05636 char tmpkeys[256]; 05637 char *stringp=NULL; 05638 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 05639 stringp=tmpkeys; 05640 keyn = strsep(&stringp, ":"); 05641 while(keyn) { 05642 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05643 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 05644 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05645 break; 05646 } else if (!key) 05647 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 05648 keyn = strsep(&stringp, ":"); 05649 } 05650 if (!keyn) { 05651 if (authdebug) 05652 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 05653 goto return_unref; 05654 } 05655 } else { 05656 if (authdebug) 05657 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 05658 goto return_unref; 05659 } 05660 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05661 struct MD5Context md5; 05662 unsigned char digest[16]; 05663 char *tmppw, *stringp; 05664 05665 tmppw = ast_strdupa(p->secret); 05666 stringp = tmppw; 05667 while((tmppw = strsep(&stringp, ";"))) { 05668 MD5Init(&md5); 05669 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 05670 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05671 MD5Final(digest, &md5); 05672 for (x=0;x<16;x++) 05673 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05674 if (!strcasecmp(requeststr, md5secret)) 05675 break; 05676 } 05677 if (tmppw) { 05678 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05679 } else { 05680 if (authdebug) 05681 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 05682 goto return_unref; 05683 } 05684 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 05685 /* They've provided a plain text password and we support that */ 05686 if (strcmp(secret, p->secret)) { 05687 if (authdebug) 05688 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05689 goto return_unref; 05690 } else 05691 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05692 } else if (!ast_strlen_zero(iaxs[callno]->secret) || !ast_strlen_zero(iaxs[callno]->inkeys)) { 05693 if (authdebug && 05694 ((!ast_strlen_zero(iaxs[callno]->secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) || 05695 (!ast_strlen_zero(iaxs[callno]->inkeys) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)))) { 05696 ast_log(LOG_NOTICE, "Inappropriate authentication received for '%s'\n", p->name); 05697 } /* ELSE this is the first time through and no challenge exists, so it's not quite yet a failure. */ 05698 goto return_unref; 05699 } 05700 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05701 05702 return_unref: 05703 ast_string_field_set(iaxs[callno], peer, peer); 05704 /* Choose lowest expiry number */ 05705 if (expire && (expire < iaxs[callno]->expiry)) 05706 iaxs[callno]->expiry = expire; 05707 05708 res = 0; 05709 05710 if (p) 05711 peer_unref(p); 05712 05713 return res; 05714 }
static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 6379 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_strdupa, ast_string_field_set, iax2_peer::authmethods, find_peer(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, 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, peer_unref(), and send_command().
Referenced by socket_process().
06380 { 06381 struct iax_ie_data ied; 06382 struct iax2_peer *p; 06383 char challenge[10]; 06384 const char *peer_name; 06385 int sentauthmethod; 06386 06387 peer_name = ast_strdupa(iaxs[callno]->peer); 06388 06389 /* SLD: third call to find_peer in registration */ 06390 ast_mutex_unlock(&iaxsl[callno]); 06391 if ((p = find_peer(peer_name, 1))) { 06392 last_authmethod = p->authmethods; 06393 } 06394 06395 ast_mutex_lock(&iaxsl[callno]); 06396 if (!iaxs[callno]) 06397 goto return_unref; 06398 06399 memset(&ied, 0, sizeof(ied)); 06400 /* The selection of which delayed reject is sent may leak information, 06401 * if it sets a static response. For example, if a host is known to only 06402 * use MD5 authentication, then an RSA response would indicate that the 06403 * peer does not exist, and vice-versa. 06404 * Therefore, we use whatever the last peer used (which may vary over the 06405 * course of a server, which should leak minimal information). */ 06406 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 06407 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod); 06408 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 06409 /* Build the challenge */ 06410 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 06411 ast_string_field_set(iaxs[callno], challenge, challenge); 06412 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 06413 } 06414 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 06415 06416 return_unref: 06417 if (p) { 06418 peer_unref(p); 06419 } 06420 06421 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1; 06422 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 6424 of file chan_iax2.c.
References iax2_registry::addr, ast_copy_string(), 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().
06425 { 06426 struct iax2_registry *reg; 06427 /* Start pessimistic */ 06428 struct iax_ie_data ied; 06429 char peer[256] = ""; 06430 char challenge[256] = ""; 06431 int res; 06432 int authmethods = 0; 06433 if (ies->authmethods) 06434 authmethods = ies->authmethods; 06435 if (ies->username) 06436 ast_copy_string(peer, ies->username, sizeof(peer)); 06437 if (ies->challenge) 06438 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 06439 memset(&ied, 0, sizeof(ied)); 06440 reg = iaxs[callno]->reg; 06441 if (reg) { 06442 if (inaddrcmp(®->addr, sin)) { 06443 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 06444 return -1; 06445 } 06446 if (ast_strlen_zero(reg->secret)) { 06447 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 06448 reg->regstate = REG_STATE_NOAUTH; 06449 return -1; 06450 } 06451 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 06452 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 06453 if (reg->secret[0] == '[') { 06454 char tmpkey[256]; 06455 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 06456 tmpkey[strlen(tmpkey) - 1] = '\0'; 06457 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL); 06458 } else 06459 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL); 06460 if (!res) { 06461 reg->regstate = REG_STATE_AUTHSENT; 06462 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 06463 } else 06464 return -1; 06465 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 06466 } else 06467 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 06468 return -1; 06469 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 4865 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().
04866 { 04867 switch(regstate) { 04868 case REG_STATE_UNREGISTERED: 04869 return "Unregistered"; 04870 case REG_STATE_REGSENT: 04871 return "Request Sent"; 04872 case REG_STATE_AUTHSENT: 04873 return "Auth. Sent"; 04874 case REG_STATE_REGISTERED: 04875 return "Registered"; 04876 case REG_STATE_REJECTED: 04877 return "Rejected"; 04878 case REG_STATE_TIMEOUT: 04879 return "Timeout"; 04880 case REG_STATE_NOAUTH: 04881 return "No Authentication"; 04882 default: 04883 return "Unknown"; 04884 } 04885 }
static int reload | ( | void | ) | [static] |
Definition at line 10380 of file chan_iax2.c.
References reload_config().
10381 { 10382 return reload_config(); 10383 }
static int reload_config | ( | void | ) | [static] |
Definition at line 10354 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, config, iax2_registry::entry, iax2_do_register(), iax_provision_reload(), poke_all_peers(), prune_peers(), prune_users(), reload_firmware(), and set_config().
10355 { 10356 char *config = "iax.conf"; 10357 struct iax2_registry *reg; 10358 10359 if (set_config(config, 1) > 0) { 10360 prune_peers(); 10361 prune_users(); 10362 AST_LIST_LOCK(®istrations); 10363 AST_LIST_TRAVERSE(®istrations, reg, entry) 10364 iax2_do_register(reg); 10365 AST_LIST_UNLOCK(®istrations); 10366 /* Qualify hosts, too */ 10367 poke_all_peers(); 10368 } 10369 reload_firmware(0); 10370 iax_provision_reload(); 10371 10372 return 0; 10373 }
static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 2018 of file chan_iax2.c.
References ast_config_AST_DATA_DIR, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), iax_firmware::dead, destroy_firmware(), errno, ast_firmware_list::lock, LOG_WARNING, iax_firmware::next, option_verbose, try_firmware(), VERBOSE_PREFIX_2, ast_firmware_list::wares, and waresl.
Referenced by __unload_module(), load_module(), and reload_config().
02019 { 02020 struct iax_firmware *cur, *curl, *curp; 02021 DIR *fwd; 02022 struct dirent *de; 02023 char dir[256]; 02024 char fn[256]; 02025 /* Mark all as dead */ 02026 ast_mutex_lock(&waresl.lock); 02027 cur = waresl.wares; 02028 while(cur) { 02029 cur->dead = 1; 02030 cur = cur->next; 02031 } 02032 02033 /* Now that we've freed them, load the new ones */ 02034 if (!unload) { 02035 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR); 02036 fwd = opendir(dir); 02037 if (fwd) { 02038 while((de = readdir(fwd))) { 02039 if (de->d_name[0] != '.') { 02040 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 02041 if (!try_firmware(fn)) { 02042 if (option_verbose > 1) 02043 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name); 02044 } 02045 } 02046 } 02047 closedir(fwd); 02048 } else 02049 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 02050 } 02051 02052 /* Clean up leftovers */ 02053 cur = waresl.wares; 02054 curp = NULL; 02055 while(cur) { 02056 curl = cur; 02057 cur = cur->next; 02058 if (curl->dead) { 02059 if (curp) { 02060 curp->next = cur; 02061 } else { 02062 waresl.wares = cur; 02063 } 02064 destroy_firmware(curl); 02065 } else { 02066 curp = cur; 02067 } 02068 } 02069 ast_mutex_unlock(&waresl.lock); 02070 }
static void remove_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1258 of file chan_iax2.c.
References ao2_unlink(), ast_log(), iax_peercallno_pvts, LOG_ERROR, and chan_iax2_pvt::peercallno.
Referenced by complete_transfer(), iax2_destroy(), and socket_process().
01259 { 01260 if (!pvt->peercallno) { 01261 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01262 return; 01263 } 01264 01265 ao2_unlink(iax_peercallno_pvts, pvt); 01266 }
Definition at line 6928 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().
06929 { 06930 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 06931 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 06932 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 06933 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 06934 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 06935 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 06936 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 06937 }
static void* sched_thread | ( | void * | ignore | ) | [static] |
Definition at line 9164 of file chan_iax2.c.
References ast_cond_timedwait(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_samp2tv(), ast_sched_runq(), ast_sched_wait(), ast_tvadd(), ast_tvnow(), option_debug, sched, and sched_lock.
Referenced by start_network_thread().
09165 { 09166 int count; 09167 int res; 09168 struct timeval tv; 09169 struct timespec ts; 09170 09171 for (;;) { 09172 pthread_testcancel(); 09173 ast_mutex_lock(&sched_lock); 09174 res = ast_sched_wait(sched); 09175 if ((res > 1000) || (res < 0)) 09176 res = 1000; 09177 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000)); 09178 ts.tv_sec = tv.tv_sec; 09179 ts.tv_nsec = tv.tv_usec * 1000; 09180 ast_cond_timedwait(&sched_cond, &sched_lock, &ts); 09181 ast_mutex_unlock(&sched_lock); 09182 pthread_testcancel(); 09183 09184 count = ast_sched_runq(sched); 09185 if (option_debug && count >= 20) 09186 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 09187 } 09188 return NULL; 09189 }
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 2708 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_samp2tv(), AST_SCHED_DEL, ast_test_flag, ast_tv(), ast_tvadd(), ast_tvzero(), calc_rxstamp(), iax_frame::callno, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, LOG_DEBUG, option_debug, ast_channel_tech::properties, sched, ast_channel::tech, iax_frame::ts, unwrap_timestamp(), and update_jbsched().
Referenced by socket_process().
02709 { 02710 int type, len; 02711 int ret; 02712 int needfree = 0; 02713 struct ast_channel *owner = NULL; 02714 struct ast_channel *bridge = NULL; 02715 02716 /* Attempt to recover wrapped timestamps */ 02717 unwrap_timestamp(fr); 02718 02719 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 02720 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 02721 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 02722 else { 02723 #if 0 02724 if (option_debug) 02725 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 02726 #endif 02727 fr->af.delivery = ast_tv(0,0); 02728 } 02729 02730 type = JB_TYPE_CONTROL; 02731 len = 0; 02732 02733 if(fr->af.frametype == AST_FRAME_VOICE) { 02734 type = JB_TYPE_VOICE; 02735 len = ast_codec_get_samples(&fr->af) / 8; 02736 } else if(fr->af.frametype == AST_FRAME_CNG) { 02737 type = JB_TYPE_SILENCE; 02738 } 02739 02740 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 02741 if (tsout) 02742 *tsout = fr->ts; 02743 __do_deliver(fr); 02744 return -1; 02745 } 02746 02747 if ((owner = iaxs[fr->callno]->owner)) 02748 bridge = ast_bridged_channel(owner); 02749 02750 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 02751 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 02752 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 02753 jb_frame frame; 02754 02755 /* deliver any frames in the jb */ 02756 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 02757 __do_deliver(frame.data); 02758 /* __do_deliver() can make the call disappear */ 02759 if (!iaxs[fr->callno]) 02760 return -1; 02761 } 02762 02763 jb_reset(iaxs[fr->callno]->jb); 02764 02765 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid); 02766 02767 /* deliver this frame now */ 02768 if (tsout) 02769 *tsout = fr->ts; 02770 __do_deliver(fr); 02771 return -1; 02772 } 02773 02774 /* insert into jitterbuffer */ 02775 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 02776 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 02777 calc_rxstamp(iaxs[fr->callno],fr->ts)); 02778 if (ret == JB_DROP) { 02779 needfree++; 02780 } else if (ret == JB_SCHED) { 02781 update_jbsched(iaxs[fr->callno]); 02782 } 02783 if (tsout) 02784 *tsout = fr->ts; 02785 if (needfree) { 02786 /* Free our iax frame */ 02787 iax2_frame_free(fr); 02788 return -1; 02789 } 02790 return 0; 02791 }
static int scheduled_destroy | ( | const void * | vid | ) | [static] |
Definition at line 1345 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_destroy(), LOG_DEBUG, option_debug, and PTR_TO_CALLNO.
Referenced by iax2_hangup().
01346 { 01347 short callno = PTR_TO_CALLNO(vid); 01348 ast_mutex_lock(&iaxsl[callno]); 01349 if (iaxs[callno]) { 01350 if (option_debug) { 01351 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno); 01352 } 01353 iax2_destroy(callno); 01354 } 01355 ast_mutex_unlock(&iaxsl[callno]); 01356 return 0; 01357 }
static int send_apathetic_reply | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | command, | |||
int | ts, | |||
unsigned char | seqno | |||
) | [static] |
Definition at line 3226 of file chan_iax2.c.
References AST_FRAME_IAX, compress_subclass(), and f.
Referenced by socket_process().
03227 { 03228 struct ast_iax2_full_hdr f = { .scallno = htons(0x8000 | callno), .dcallno = htons(dcallno), 03229 .ts = htonl(ts), .iseqno = seqno, .oseqno = 0, .type = AST_FRAME_IAX, 03230 .csub = compress_subclass(command) }; 03231 03232 return sendto(defaultsockfd, &f, sizeof(f), 0, (struct sockaddr *)sin, sizeof(*sin)); 03233 }
static int send_command | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 5149 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().
05150 { 05151 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 05152 }
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 5168 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().
05169 { 05170 int call_num = i->callno; 05171 /* It is assumed that the callno has already been locked */ 05172 iax2_predestroy(i->callno); 05173 if (!iaxs[call_num]) 05174 return -1; 05175 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 05176 }
static int send_command_immediate | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 5178 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
05179 { 05180 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 05181 }
static int send_command_locked | ( | unsigned short | callno, | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 5154 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().
05155 { 05156 int res; 05157 ast_mutex_lock(&iaxsl[callno]); 05158 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 05159 ast_mutex_unlock(&iaxsl[callno]); 05160 return res; 05161 }
static int send_command_transfer | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | ||||
) | [static] |
Definition at line 5183 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
05184 { 05185 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 05186 }
static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1063 of file chan_iax2.c.
References __send_lagrq(), and schedule_action.
Referenced by __find_callno(), __send_lagrq(), and make_trunk().
01064 { 01065 #ifdef SCHED_MULTITHREADED 01066 if (schedule_action(__send_lagrq, data)) 01067 #endif 01068 __send_lagrq(data); 01069 01070 return 0; 01071 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2143 of file chan_iax2.c.
References chan_iax2_pvt::addr, ast_inet_ntoa(), ast_log(), iax2_registry::callno, errno, f, handle_error(), iax_showframe(), iaxs, LOG_DEBUG, option_debug, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, and transfer.
Referenced by __attempt_transmit(), iax2_send(), network_thread(), and vnak_retransmit().
02144 { 02145 int res; 02146 int callno = f->callno; 02147 02148 /* Don't send if there was an error, but return error instead */ 02149 if (!callno || !iaxs[callno] || iaxs[callno]->error) 02150 return -1; 02151 02152 /* Called with iaxsl held */ 02153 if (option_debug > 2 && iaxdebug) 02154 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)); 02155 if (f->transfer) { 02156 if (iaxdebug) 02157 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 02158 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, 02159 sizeof(iaxs[callno]->transfer)); 02160 } else { 02161 if (iaxdebug) 02162 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 02163 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, 02164 sizeof(iaxs[callno]->addr)); 02165 } 02166 if (res < 0) { 02167 if (option_debug && iaxdebug) 02168 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 02169 handle_error(); 02170 } else 02171 res = 0; 02172 return res; 02173 }
static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 1018 of file chan_iax2.c.
References __send_ping(), and schedule_action.
Referenced by __find_callno(), __send_ping(), and make_trunk().
01019 { 01020 #ifdef SCHED_MULTITHREADED 01021 if (schedule_action(__send_ping, data)) 01022 #endif 01023 __send_ping(data); 01024 01025 return 0; 01026 }
static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [static] |
Definition at line 6606 of file chan_iax2.c.
References iax2_trunk_peer::addr, iax_frame::afdata, ast_inet_ntoa(), ast_log(), ast_test_flag, calc_txpeerstamp(), iax2_trunk_peer::calls, ast_iax2_meta_hdr::cmddata, iax_frame::data, ast_iax2_meta_hdr::data, iax_frame::datalen, iax_frame::direction, DIRECTION_OUTGRESS, globalflags, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_hdr::metacmd, option_debug, iax_frame::retrans, iax2_trunk_peer::sockfd, iax_frame::transfer, transmit_trunk(), iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdatalen, ast_iax2_meta_trunk_hdr::ts, and ast_iax2_meta_hdr::zeros.
Referenced by timing_read().
06607 { 06608 int res = 0; 06609 struct iax_frame *fr; 06610 struct ast_iax2_meta_hdr *meta; 06611 struct ast_iax2_meta_trunk_hdr *mth; 06612 int calls = 0; 06613 06614 /* Point to frame */ 06615 fr = (struct iax_frame *)tpeer->trunkdata; 06616 /* Point to meta data */ 06617 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 06618 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 06619 if (tpeer->trunkdatalen) { 06620 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 06621 meta->zeros = 0; 06622 meta->metacmd = IAX_META_TRUNK; 06623 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 06624 meta->cmddata = IAX_META_TRUNK_MINI; 06625 else 06626 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 06627 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 06628 /* And the rest of the ast_iax2 header */ 06629 fr->direction = DIRECTION_OUTGRESS; 06630 fr->retrans = -1; 06631 fr->transfer = 0; 06632 /* Any appropriate call will do */ 06633 fr->data = fr->afdata; 06634 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 06635 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 06636 calls = tpeer->calls; 06637 #if 0 06638 if (option_debug) 06639 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)); 06640 #endif 06641 /* Reset transmit trunk side data */ 06642 tpeer->trunkdatalen = 0; 06643 tpeer->calls = 0; 06644 } 06645 if (res < 0) 06646 return res; 06647 return calls; 06648 }
static int set_config | ( | char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 9984 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_copy_string(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_netsock_bind(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_netsock_sockfd(), ast_netsock_unref(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_str2tos(), ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), build_peer(), build_user(), capability, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), globalflags, iax2_register(), IAX_ALLOWFWDOWNLOAD, IAX_CAPABILITY_FULLBANDWIDTH, IAX_CAPABILITY_LOWBANDWIDTH, IAX_CAPABILITY_MEDBANDWIDTH, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTUPDATE, IAX_TRANSFERMEDIA, IAX_TRUNKTIMESTAMPS, IAX_USEJITTERBUF, iaxmaxthreadcount, iaxthreadcount, io, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_PEER_BUCKETS, ast_variable::name, netsock, ast_variable::next, option_verbose, outsock, peer_unref(), portno, prefs, reg_source_db(), secret, set_config_destroy(), set_timing(), socket_read(), user_unref(), ast_variable::value, and VERBOSE_PREFIX_2.
Referenced by load_module(), reload(), and reload_config().
09985 { 09986 struct ast_config *cfg, *ucfg; 09987 int capability=iax2_capability; 09988 struct ast_variable *v; 09989 char *cat; 09990 const char *utype; 09991 const char *tosval; 09992 int format; 09993 int portno = IAX_DEFAULT_PORTNO; 09994 int x; 09995 struct iax2_user *user; 09996 struct iax2_peer *peer; 09997 struct ast_netsock *ns; 09998 #if 0 09999 static unsigned short int last_port=0; 10000 #endif 10001 10002 cfg = ast_config_load(config_file); 10003 10004 if (!cfg) { 10005 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 10006 return -1; 10007 } 10008 10009 if (reload) { 10010 set_config_destroy(); 10011 } 10012 10013 /* Reset global codec prefs */ 10014 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 10015 10016 /* Reset Global Flags */ 10017 memset(&globalflags, 0, sizeof(globalflags)); 10018 ast_set_flag(&globalflags, IAX_RTUPDATE); 10019 10020 #ifdef SO_NO_CHECK 10021 nochecksums = 0; 10022 #endif 10023 10024 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 10025 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 10026 10027 maxauthreq = 3; 10028 10029 v = ast_variable_browse(cfg, "general"); 10030 10031 /* Seed initial tos value */ 10032 tosval = ast_variable_retrieve(cfg, "general", "tos"); 10033 if (tosval) { 10034 if (ast_str2tos(tosval, &tos)) 10035 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n"); 10036 } 10037 while(v) { 10038 if (!strcasecmp(v->name, "bindport")){ 10039 if (reload) 10040 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 10041 else 10042 portno = atoi(v->value); 10043 } else if (!strcasecmp(v->name, "pingtime")) 10044 ping_time = atoi(v->value); 10045 else if (!strcasecmp(v->name, "iaxthreadcount")) { 10046 if (reload) { 10047 if (atoi(v->value) != iaxthreadcount) 10048 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 10049 } else { 10050 iaxthreadcount = atoi(v->value); 10051 if (iaxthreadcount < 1) { 10052 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 10053 iaxthreadcount = 1; 10054 } else if (iaxthreadcount > 256) { 10055 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 10056 iaxthreadcount = 256; 10057 } 10058 } 10059 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 10060 if (reload) { 10061 AST_LIST_LOCK(&dynamic_list); 10062 iaxmaxthreadcount = atoi(v->value); 10063 AST_LIST_UNLOCK(&dynamic_list); 10064 } else { 10065 iaxmaxthreadcount = atoi(v->value); 10066 if (iaxmaxthreadcount < 0) { 10067 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 10068 iaxmaxthreadcount = 0; 10069 } else if (iaxmaxthreadcount > 256) { 10070 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 10071 iaxmaxthreadcount = 256; 10072 } 10073 } 10074 } else if (!strcasecmp(v->name, "nochecksums")) { 10075 #ifdef SO_NO_CHECK 10076 if (ast_true(v->value)) 10077 nochecksums = 1; 10078 else 10079 nochecksums = 0; 10080 #else 10081 if (ast_true(v->value)) 10082 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 10083 #endif 10084 } 10085 else if (!strcasecmp(v->name, "maxjitterbuffer")) 10086 maxjitterbuffer = atoi(v->value); 10087 else if (!strcasecmp(v->name, "resyncthreshold")) 10088 resyncthreshold = atoi(v->value); 10089 else if (!strcasecmp(v->name, "maxjitterinterps")) 10090 maxjitterinterps = atoi(v->value); 10091 else if (!strcasecmp(v->name, "lagrqtime")) 10092 lagrq_time = atoi(v->value); 10093 else if (!strcasecmp(v->name, "maxregexpire")) 10094 max_reg_expire = atoi(v->value); 10095 else if (!strcasecmp(v->name, "minregexpire")) 10096 min_reg_expire = atoi(v->value); 10097 else if (!strcasecmp(v->name, "bindaddr")) { 10098 if (reload) { 10099 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 10100 } else { 10101 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) { 10102 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 10103 } else { 10104 if (option_verbose > 1) { 10105 if (strchr(v->value, ':')) 10106 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value); 10107 else 10108 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno); 10109 } 10110 if (defaultsockfd < 0) 10111 defaultsockfd = ast_netsock_sockfd(ns); 10112 ast_netsock_unref(ns); 10113 } 10114 } 10115 } else if (!strcasecmp(v->name, "authdebug")) 10116 authdebug = ast_true(v->value); 10117 else if (!strcasecmp(v->name, "encryption")) 10118 iax2_encryption = get_encrypt_methods(v->value); 10119 else if (!strcasecmp(v->name, "notransfer")) { 10120 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 10121 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 10122 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER); 10123 } else if (!strcasecmp(v->name, "transfer")) { 10124 if (!strcasecmp(v->value, "mediaonly")) { 10125 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 10126 } else if (ast_true(v->value)) { 10127 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 10128 } else 10129 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 10130 } else if (!strcasecmp(v->name, "codecpriority")) { 10131 if(!strcasecmp(v->value, "caller")) 10132 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 10133 else if(!strcasecmp(v->value, "disabled")) 10134 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 10135 else if(!strcasecmp(v->value, "reqonly")) { 10136 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 10137 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 10138 } 10139 } else if (!strcasecmp(v->name, "jitterbuffer")) 10140 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 10141 else if (!strcasecmp(v->name, "forcejitterbuffer")) 10142 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 10143 else if (!strcasecmp(v->name, "delayreject")) 10144 delayreject = ast_true(v->value); 10145 else if (!strcasecmp(v->name, "allowfwdownload")) 10146 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 10147 else if (!strcasecmp(v->name, "rtcachefriends")) 10148 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 10149 else if (!strcasecmp(v->name, "rtignoreregexpire")) 10150 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 10151 else if (!strcasecmp(v->name, "rtupdate")) 10152 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 10153 else if (!strcasecmp(v->name, "trunktimestamps")) 10154 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 10155 else if (!strcasecmp(v->name, "rtautoclear")) { 10156 int i = atoi(v->value); 10157 if(i > 0) 10158 global_rtautoclear = i; 10159 else 10160 i = 0; 10161 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 10162 } else if (!strcasecmp(v->name, "trunkfreq")) { 10163 trunkfreq = atoi(v->value); 10164 if (trunkfreq < 10) 10165 trunkfreq = 10; 10166 } else if (!strcasecmp(v->name, "autokill")) { 10167 if (sscanf(v->value, "%d", &x) == 1) { 10168 if (x >= 0) 10169 autokill = x; 10170 else 10171 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 10172 } else if (ast_true(v->value)) { 10173 autokill = DEFAULT_MAXMS; 10174 } else { 10175 autokill = 0; 10176 } 10177 } else if (!strcasecmp(v->name, "bandwidth")) { 10178 if (!strcasecmp(v->value, "low")) { 10179 capability = IAX_CAPABILITY_LOWBANDWIDTH; 10180 } else if (!strcasecmp(v->value, "medium")) { 10181 capability = IAX_CAPABILITY_MEDBANDWIDTH; 10182 } else if (!strcasecmp(v->value, "high")) { 10183 capability = IAX_CAPABILITY_FULLBANDWIDTH; 10184 } else 10185 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 10186 } else if (!strcasecmp(v->name, "allow")) { 10187 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 10188 } else if (!strcasecmp(v->name, "disallow")) { 10189 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 10190 } else if (!strcasecmp(v->name, "register")) { 10191 iax2_register(v->value, v->lineno); 10192 } else if (!strcasecmp(v->name, "iaxcompat")) { 10193 iaxcompat = ast_true(v->value); 10194 } else if (!strcasecmp(v->name, "regcontext")) { 10195 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 10196 /* Create context if it doesn't exist already */ 10197 if (!ast_context_find(regcontext)) 10198 ast_context_create(NULL, regcontext, "IAX2"); 10199 } else if (!strcasecmp(v->name, "tos")) { 10200 if (ast_str2tos(v->value, &tos)) 10201 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno); 10202 } else if (!strcasecmp(v->name, "accountcode")) { 10203 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 10204 } else if (!strcasecmp(v->name, "mohinterpret")) { 10205 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret)); 10206 } else if (!strcasecmp(v->name, "mohsuggest")) { 10207 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest)); 10208 } else if (!strcasecmp(v->name, "amaflags")) { 10209 format = ast_cdr_amaflags2int(v->value); 10210 if (format < 0) { 10211 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 10212 } else { 10213 amaflags = format; 10214 } 10215 } else if (!strcasecmp(v->name, "language")) { 10216 ast_copy_string(language, v->value, sizeof(language)); 10217 } else if (!strcasecmp(v->name, "maxauthreq")) { 10218 maxauthreq = atoi(v->value); 10219 if (maxauthreq < 0) 10220 maxauthreq = 0; 10221 } else if (!strcasecmp(v->name, "adsi")) { 10222 adsi = ast_true(v->value); 10223 } /*else if (strcasecmp(v->name,"type")) */ 10224 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 10225 v = v->next; 10226 } 10227 10228 if (defaultsockfd < 0) { 10229 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) { 10230 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 10231 } else { 10232 if (option_verbose > 1) 10233 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 10234 defaultsockfd = ast_netsock_sockfd(ns); 10235 ast_netsock_unref(ns); 10236 } 10237 } 10238 if (reload) { 10239 ast_netsock_release(outsock); 10240 outsock = ast_netsock_list_alloc(); 10241 if (!outsock) { 10242 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 10243 return -1; 10244 } 10245 ast_netsock_init(outsock); 10246 } 10247 10248 if (min_reg_expire > max_reg_expire) { 10249 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 10250 min_reg_expire, max_reg_expire, max_reg_expire); 10251 min_reg_expire = max_reg_expire; 10252 } 10253 iax2_capability = capability; 10254 10255 ucfg = ast_config_load("users.conf"); 10256 if (ucfg) { 10257 struct ast_variable *gen; 10258 int genhasiax; 10259 int genregisteriax; 10260 const char *hasiax, *registeriax; 10261 10262 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 10263 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 10264 gen = ast_variable_browse(ucfg, "general"); 10265 cat = ast_category_browse(ucfg, NULL); 10266 while (cat) { 10267 if (strcasecmp(cat, "general")) { 10268 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 10269 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 10270 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 10271 /* Start with general parameters, then specific parameters, user and peer */ 10272 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 10273 if (user) { 10274 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10275 user = user_unref(user); 10276 } 10277 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 10278 if (peer) { 10279 if (ast_test_flag(peer, IAX_DYNAMIC)) 10280 reg_source_db(peer); 10281 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10282 peer = peer_unref(peer); 10283 } 10284 } 10285 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 10286 char tmp[256]; 10287 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 10288 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 10289 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 10290 if (!host) 10291 host = ast_variable_retrieve(ucfg, "general", "host"); 10292 if (!username) 10293 username = ast_variable_retrieve(ucfg, "general", "username"); 10294 if (!secret) 10295 secret = ast_variable_retrieve(ucfg, "general", "secret"); 10296 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 10297 if (!ast_strlen_zero(secret)) 10298 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 10299 else 10300 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 10301 iax2_register(tmp, 0); 10302 } 10303 } 10304 } 10305 cat = ast_category_browse(ucfg, cat); 10306 } 10307 ast_config_destroy(ucfg); 10308 } 10309 10310 cat = ast_category_browse(cfg, NULL); 10311 while(cat) { 10312 if (strcasecmp(cat, "general")) { 10313 utype = ast_variable_retrieve(cfg, cat, "type"); 10314 if (utype) { 10315 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 10316 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 10317 if (user) { 10318 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10319 user = user_unref(user); 10320 } 10321 } 10322 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 10323 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 10324 if (peer) { 10325 if (ast_test_flag(peer, IAX_DYNAMIC)) 10326 reg_source_db(peer); 10327 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10328 peer = peer_unref(peer); 10329 } 10330 } else if (strcasecmp(utype, "user")) { 10331 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 10332 } 10333 } else 10334 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 10335 } 10336 cat = ast_category_browse(cfg, cat); 10337 } 10338 ast_config_destroy(cfg); 10339 set_timing(); 10340 return 1; 10341 }
static void set_config_destroy | ( | void | ) | [static] |
Definition at line 9968 of file chan_iax2.c.
References ast_clear_flag, delete_users(), globalflags, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, and IAX_USEJITTERBUF.
Referenced by set_config().
09969 { 09970 strcpy(accountcode, ""); 09971 strcpy(language, ""); 09972 strcpy(mohinterpret, "default"); 09973 strcpy(mohsuggest, ""); 09974 amaflags = 0; 09975 delayreject = 0; 09976 ast_clear_flag((&globalflags), IAX_NOTRANSFER); 09977 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 09978 ast_clear_flag((&globalflags), IAX_USEJITTERBUF); 09979 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF); 09980 delete_users(); 09981 }
static void set_timing | ( | void | ) | [static] |
Definition at line 9953 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by set_config().
09954 { 09955 #ifdef HAVE_DAHDI 09956 int bs = trunkfreq * 8; 09957 if (timingfd > -1) { 09958 if ( 09959 #ifdef DAHDI_TIMERACK 09960 ioctl(timingfd, DAHDI_TIMERCONFIG, &bs) && 09961 #endif 09962 ioctl(timingfd, DAHDI_SET_BLOCKSIZE, &bs)) 09963 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n"); 09964 } 09965 #endif 09966 }
static void signal_condition | ( | ast_mutex_t * | lock, | |
ast_cond_t * | cond | |||
) | [static] |
Definition at line 756 of file chan_iax2.c.
References ast_cond_signal(), ast_mutex_lock(), and ast_mutex_unlock().
Referenced by __schedule_action(), iax2_sched_add(), iax2_transmit(), and socket_read().
00757 { 00758 ast_mutex_lock(lock); 00759 ast_cond_signal(cond); 00760 ast_mutex_unlock(lock); 00761 }
static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 7080 of file chan_iax2.c.
References ast_async_goto(), ast_best_codec(), ast_bridged_channel(), AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, 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_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_UNHOLD, ast_device_state_changed(), ast_exists_extension(), AST_FORMAT_SLINEAR, ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_IAX, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname(), ast_iax2_new(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_parking_ext(), ast_sched_del(), AST_SCHED_DEL, ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_tvnow(), ast_tvzero(), ast_verbose(), auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, calc_timestamp(), iax2_peer::callno, iax2_dpcache::callno, iax_frame::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, check_access(), check_provisioning(), cid_num, complete_dpreply(), complete_transfer(), construct_rr(), ast_channel::context, DEADLOCK_AVOIDANCE, decrypt_frame(), dp_lookup(), dpcache_lock, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, f, iax_frame::final, find_callno(), find_callno_locked(), find_tpeer(), fix_peerts(), iax2_dpcache::flags, format, chan_iax2_pvt::frames_received, ast_frame::frametype, globalflags, ast_channel::hangupcause, iax2_peer::historicms, iax2_ack_registry(), iax2_destroy(), iax2_dprequest(), iax2_poke_peer_s(), iax2_queue_control_data(), iax2_queue_frame(), iax2_sched_add(), iax2_send(), iax2_vnak(), IAX_ALLOWFWDOWNLOAD, IAX_ALREADYGONE, IAX_AUTH_MD5, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_NEW, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXMEDIA, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, IAX_COMMAND_VNAK, IAX_DELAYPBXSTART, IAX_ENCRYPTED, iax_firmware_append(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, iax_frame_wrap(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLNO, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_FORMAT, IAX_IE_IAX_UNKNOWN, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, iax_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, iax_showframe(), IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_STATE_UNCHANGED, IAX_TRUNK, iaxfrdup2(), iaxq, iaxs, iaxsl, ies, inaddrcmp(), chan_iax2_pvt::iseqno, chan_iax2_pvt::last, iax2_peer::lastms, ast_iax2_meta_trunk_mini::len, 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, iax2_peer::name, ast_channel::name, NEW_ALLOW, NEW_PREVENT, option_debug, option_verbose, iax_frame::oseqno, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), iax2_dpcache::peer, peer_ref(), peer_unref(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, ast_iax2_queue::queue, raw_hangup(), REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), remove_by_peercallno(), iax_frame::retries, chan_iax2_pvt::rseqno, iax2_trunk_peer::rxtrunktime, S_OR, save_rr(), sched, schedule_delivery(), send_apathetic_reply(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), iax2_peer::smoothing, spawn_dp_lookup(), stop_stuff(), store_by_peercallno(), thread, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MREADY, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, iax2_trunk_peer::trunkact, try_transfer(), iax_frame::ts, ast_iax2_mini_hdr::ts, uncompress_subclass(), update_registry(), VERBOSE_PREFIX_3, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, and ast_iax2_meta_hdr::zeros.
Referenced by handle_deferred_full_frames().
07081 { 07082 struct sockaddr_in sin; 07083 int res; 07084 int updatehistory=1; 07085 int new = NEW_PREVENT; 07086 void *ptr; 07087 int dcallno = 0; 07088 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 07089 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 07090 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 07091 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 07092 struct ast_iax2_meta_trunk_hdr *mth; 07093 struct ast_iax2_meta_trunk_entry *mte; 07094 struct ast_iax2_meta_trunk_mini *mtm; 07095 struct iax_frame *fr; 07096 struct iax_frame *cur; 07097 struct ast_frame f = { 0, }; 07098 struct ast_channel *c; 07099 struct iax2_dpcache *dp; 07100 struct iax2_peer *peer; 07101 struct iax2_trunk_peer *tpeer; 07102 struct timeval rxtrunktime; 07103 struct iax_ies ies; 07104 struct iax_ie_data ied0, ied1; 07105 int format; 07106 int fd; 07107 int exists; 07108 int minivid = 0; 07109 unsigned int ts; 07110 char empty[32]=""; /* Safety measure */ 07111 struct iax_frame *duped_fr; 07112 char host_pref_buf[128]; 07113 char caller_pref_buf[128]; 07114 struct ast_codec_pref pref; 07115 char *using_prefs = "mine"; 07116 07117 /* allocate an iax_frame with 4096 bytes of data buffer */ 07118 fr = alloca(sizeof(*fr) + 4096); 07119 memset(fr, 0, sizeof(*fr)); 07120 fr->afdatalen = 4096; /* From alloca() above */ 07121 07122 /* Copy frequently used parameters to the stack */ 07123 res = thread->buf_len; 07124 fd = thread->iofd; 07125 memcpy(&sin, &thread->iosin, sizeof(sin)); 07126 07127 if (res < sizeof(*mh)) { 07128 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh)); 07129 return 1; 07130 } 07131 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 07132 if (res < sizeof(*vh)) { 07133 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)); 07134 return 1; 07135 } 07136 07137 /* This is a video frame, get call number */ 07138 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 07139 minivid = 1; 07140 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) { 07141 unsigned char metatype; 07142 07143 if (res < sizeof(*meta)) { 07144 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)); 07145 return 1; 07146 } 07147 07148 /* This is a meta header */ 07149 switch(meta->metacmd) { 07150 case IAX_META_TRUNK: 07151 if (res < (sizeof(*meta) + sizeof(*mth))) { 07152 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res, 07153 sizeof(*meta) + sizeof(*mth)); 07154 return 1; 07155 } 07156 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 07157 ts = ntohl(mth->ts); 07158 metatype = meta->cmddata; 07159 res -= (sizeof(*meta) + sizeof(*mth)); 07160 ptr = mth->data; 07161 tpeer = find_tpeer(&sin, fd); 07162 if (!tpeer) { 07163 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)); 07164 return 1; 07165 } 07166 tpeer->trunkact = ast_tvnow(); 07167 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 07168 tpeer->rxtrunktime = tpeer->trunkact; 07169 rxtrunktime = tpeer->rxtrunktime; 07170 ast_mutex_unlock(&tpeer->lock); 07171 while(res >= sizeof(*mte)) { 07172 /* Process channels */ 07173 unsigned short callno, trunked_ts, len; 07174 07175 if (metatype == IAX_META_TRUNK_MINI) { 07176 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 07177 ptr += sizeof(*mtm); 07178 res -= sizeof(*mtm); 07179 len = ntohs(mtm->len); 07180 callno = ntohs(mtm->mini.callno); 07181 trunked_ts = ntohs(mtm->mini.ts); 07182 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 07183 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 07184 ptr += sizeof(*mte); 07185 res -= sizeof(*mte); 07186 len = ntohs(mte->len); 07187 callno = ntohs(mte->callno); 07188 trunked_ts = 0; 07189 } else { 07190 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 07191 break; 07192 } 07193 /* Stop if we don't have enough data */ 07194 if (len > res) 07195 break; 07196 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0); 07197 if (fr->callno) { 07198 /* If it's a valid call, deliver the contents. If not, we 07199 drop it, since we don't have a scallno to use for an INVAL */ 07200 /* Process as a mini frame */ 07201 memset(&f, 0, sizeof(f)); 07202 f.frametype = AST_FRAME_VOICE; 07203 if (iaxs[fr->callno]) { 07204 if (iaxs[fr->callno]->voiceformat > 0) { 07205 f.subclass = iaxs[fr->callno]->voiceformat; 07206 f.datalen = len; 07207 if (f.datalen >= 0) { 07208 if (f.datalen) 07209 f.data = ptr; 07210 if(trunked_ts) { 07211 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 07212 } else 07213 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 07214 /* Don't pass any packets until we're started */ 07215 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07216 /* Common things */ 07217 f.src = "IAX2"; 07218 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 07219 f.samples = ast_codec_get_samples(&f); 07220 iax_frame_wrap(fr, &f); 07221 duped_fr = iaxfrdup2(fr); 07222 if (duped_fr) { 07223 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); 07224 } 07225 /* It is possible for the pvt structure to go away after we call schedule_delivery */ 07226 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 07227 iaxs[fr->callno]->last = fr->ts; 07228 #if 1 07229 if (option_debug && iaxdebug) 07230 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07231 #endif 07232 } 07233 } 07234 } else { 07235 ast_log(LOG_WARNING, "Datalen < 0?\n"); 07236 } 07237 } else { 07238 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n"); 07239 iax2_vnak(fr->callno); 07240 } 07241 } 07242 ast_mutex_unlock(&iaxsl[fr->callno]); 07243 } 07244 ptr += len; 07245 res -= len; 07246 } 07247 07248 } 07249 return 1; 07250 } 07251 07252 #ifdef DEBUG_SUPPORT 07253 if (iaxdebug && (res >= sizeof(*fh))) 07254 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 07255 #endif 07256 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07257 if (res < sizeof(*fh)) { 07258 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)); 07259 return 1; 07260 } 07261 07262 /* Get the destination call number */ 07263 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 07264 /* Retrieve the type and subclass */ 07265 f.frametype = fh->type; 07266 if (f.frametype == AST_FRAME_VIDEO) { 07267 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 07268 } else { 07269 f.subclass = uncompress_subclass(fh->csub); 07270 } 07271 07272 /* Deal with POKE/PONG without allocating a callno */ 07273 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) { 07274 /* Reply back with a PONG, but don't care about the result. */ 07275 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohs(fh->ts), fh->iseqno + 1); 07276 return 1; 07277 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) { 07278 /* Ignore */ 07279 return 1; 07280 } 07281 07282 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) || 07283 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) || 07284 (f.subclass == IAX_COMMAND_REGREL))) 07285 new = NEW_ALLOW; 07286 } else { 07287 /* Don't know anything about it yet */ 07288 f.frametype = AST_FRAME_NULL; 07289 f.subclass = 0; 07290 } 07291 07292 if (!fr->callno) { 07293 int check_dcallno = 0; 07294 07295 /* 07296 * We enforce accurate destination call numbers for all full frames except 07297 * LAGRQ and PING commands. This is because older versions of Asterisk 07298 * schedule these commands to get sent very quickly, and they will sometimes 07299 * be sent before they receive the first frame from the other side. When 07300 * that happens, it doesn't contain the destination call number. However, 07301 * not checking it for these frames is safe. 07302 * 07303 * Discussed in the following thread: 07304 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 07305 */ 07306 07307 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07308 check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1; 07309 } 07310 07311 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno); 07312 } 07313 07314 if (fr->callno > 0) 07315 ast_mutex_lock(&iaxsl[fr->callno]); 07316 07317 if (!fr->callno || !iaxs[fr->callno]) { 07318 /* A call arrived for a nonexistent destination. Unless it's an "inval" 07319 frame, reply with an inval */ 07320 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07321 /* We can only raw hangup control frames */ 07322 if (((f.subclass != IAX_COMMAND_INVAL) && 07323 (f.subclass != IAX_COMMAND_TXCNT) && 07324 (f.subclass != IAX_COMMAND_TXACC) && 07325 (f.subclass != IAX_COMMAND_FWDOWNL))|| 07326 (f.frametype != AST_FRAME_IAX)) 07327 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 07328 fd); 07329 } 07330 if (fr->callno > 0) 07331 ast_mutex_unlock(&iaxsl[fr->callno]); 07332 return 1; 07333 } 07334 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { 07335 if (decrypt_frame(fr->callno, fh, &f, &res)) { 07336 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 07337 ast_mutex_unlock(&iaxsl[fr->callno]); 07338 return 1; 07339 } 07340 #ifdef DEBUG_SUPPORT 07341 else if (iaxdebug) 07342 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 07343 #endif 07344 } 07345 07346 /* count this frame */ 07347 iaxs[fr->callno]->frames_received++; 07348 07349 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 07350 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 07351 f.subclass != IAX_COMMAND_TXACC) { /* for attended transfer */ 07352 unsigned short new_peercallno; 07353 07354 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 07355 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 07356 if (iaxs[fr->callno]->peercallno) { 07357 remove_by_peercallno(iaxs[fr->callno]); 07358 } 07359 iaxs[fr->callno]->peercallno = new_peercallno; 07360 store_by_peercallno(iaxs[fr->callno]); 07361 } 07362 } 07363 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07364 if (option_debug && iaxdebug) 07365 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 07366 /* Check if it's out of order (and not an ACK or INVAL) */ 07367 fr->oseqno = fh->oseqno; 07368 fr->iseqno = fh->iseqno; 07369 fr->ts = ntohl(fh->ts); 07370 #ifdef IAXTESTS 07371 if (test_resync) { 07372 if (option_debug) 07373 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 07374 fr->ts += test_resync; 07375 } 07376 #endif /* IAXTESTS */ 07377 #if 0 07378 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 07379 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 07380 (f.subclass == IAX_COMMAND_NEW || 07381 f.subclass == IAX_COMMAND_AUTHREQ || 07382 f.subclass == IAX_COMMAND_ACCEPT || 07383 f.subclass == IAX_COMMAND_REJECT)) ) ) 07384 #endif 07385 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 07386 updatehistory = 0; 07387 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 07388 (iaxs[fr->callno]->iseqno || 07389 ((f.subclass != IAX_COMMAND_TXCNT) && 07390 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 07391 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 07392 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 07393 (f.subclass != IAX_COMMAND_TXACC)) || 07394 (f.frametype != AST_FRAME_IAX))) { 07395 if ( 07396 ((f.subclass != IAX_COMMAND_ACK) && 07397 (f.subclass != IAX_COMMAND_INVAL) && 07398 (f.subclass != IAX_COMMAND_TXCNT) && 07399 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 07400 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 07401 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 07402 (f.subclass != IAX_COMMAND_TXACC) && 07403 (f.subclass != IAX_COMMAND_VNAK)) || 07404 (f.frametype != AST_FRAME_IAX)) { 07405 /* If it's not an ACK packet, it's out of order. */ 07406 if (option_debug) 07407 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 07408 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); 07409 /* Check to see if we need to request retransmission, 07410 * and take sequence number wraparound into account */ 07411 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 07412 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 07413 if ((f.frametype != AST_FRAME_IAX) || 07414 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 07415 if (option_debug) 07416 ast_log(LOG_DEBUG, "Acking anyway\n"); 07417 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 07418 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 07419 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07420 } 07421 } else { 07422 /* Send a VNAK requesting retransmission */ 07423 iax2_vnak(fr->callno); 07424 } 07425 ast_mutex_unlock(&iaxsl[fr->callno]); 07426 return 1; 07427 } 07428 } else { 07429 /* Increment unless it's an ACK or VNAK */ 07430 if (((f.subclass != IAX_COMMAND_ACK) && 07431 (f.subclass != IAX_COMMAND_INVAL) && 07432 (f.subclass != IAX_COMMAND_TXCNT) && 07433 (f.subclass != IAX_COMMAND_TXACC) && 07434 (f.subclass != IAX_COMMAND_VNAK)) || 07435 (f.frametype != AST_FRAME_IAX)) 07436 iaxs[fr->callno]->iseqno++; 07437 } 07438 /* A full frame */ 07439 if (res < sizeof(*fh)) { 07440 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh)); 07441 ast_mutex_unlock(&iaxsl[fr->callno]); 07442 return 1; 07443 } 07444 /* Ensure text frames are NULL-terminated */ 07445 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 07446 if (res < thread->buf_size) 07447 thread->buf[res++] = '\0'; 07448 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 07449 thread->buf[res - 1] = '\0'; 07450 } 07451 f.datalen = res - sizeof(*fh); 07452 07453 /* Handle implicit ACKing unless this is an INVAL, and only if this is 07454 from the real peer, not the transfer peer */ 07455 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07456 ((f.subclass != IAX_COMMAND_INVAL) || 07457 (f.frametype != AST_FRAME_IAX))) { 07458 unsigned char x; 07459 int call_to_destroy; 07460 /* XXX This code is not very efficient. Surely there is a better way which still 07461 properly handles boundary conditions? XXX */ 07462 /* First we have to qualify that the ACKed value is within our window */ 07463 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++) 07464 if (fr->iseqno == x) 07465 break; 07466 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 07467 /* The acknowledgement is within our window. Time to acknowledge everything 07468 that it says to */ 07469 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 07470 /* Ack the packet with the given timestamp */ 07471 if (option_debug && iaxdebug) 07472 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x); 07473 call_to_destroy = 0; 07474 AST_LIST_LOCK(&iaxq.queue); 07475 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07476 /* If it's our call, and our timestamp, mark -1 retries */ 07477 if ((fr->callno == cur->callno) && (x == cur->oseqno)) { 07478 cur->retries = -1; 07479 /* Destroy call if this is the end */ 07480 if (cur->final) 07481 call_to_destroy = fr->callno; 07482 } 07483 } 07484 AST_LIST_UNLOCK(&iaxq.queue); 07485 if (call_to_destroy) { 07486 if (iaxdebug && option_debug) 07487 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy); 07488 ast_mutex_lock(&iaxsl[call_to_destroy]); 07489 iax2_destroy(call_to_destroy); 07490 ast_mutex_unlock(&iaxsl[call_to_destroy]); 07491 } 07492 } 07493 /* Note how much we've received acknowledgement for */ 07494 if (iaxs[fr->callno]) 07495 iaxs[fr->callno]->rseqno = fr->iseqno; 07496 else { 07497 /* Stop processing now */ 07498 ast_mutex_unlock(&iaxsl[fr->callno]); 07499 return 1; 07500 } 07501 } else if (option_debug) 07502 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 07503 } 07504 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07505 ((f.frametype != AST_FRAME_IAX) || 07506 ((f.subclass != IAX_COMMAND_TXACC) && 07507 (f.subclass != IAX_COMMAND_TXCNT)))) { 07508 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 07509 ast_mutex_unlock(&iaxsl[fr->callno]); 07510 return 1; 07511 } 07512 07513 if (f.datalen) { 07514 if (f.frametype == AST_FRAME_IAX) { 07515 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) { 07516 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 07517 ast_mutex_unlock(&iaxsl[fr->callno]); 07518 return 1; 07519 } 07520 f.data = NULL; 07521 f.datalen = 0; 07522 } else 07523 f.data = thread->buf + sizeof(*fh); 07524 } else { 07525 if (f.frametype == AST_FRAME_IAX) 07526 f.data = NULL; 07527 else 07528 f.data = empty; 07529 memset(&ies, 0, sizeof(ies)); 07530 } 07531 07532 /* when we receive the first full frame for a new incoming channel, 07533 it is safe to start the PBX on the channel because we have now 07534 completed a 3-way handshake with the peer */ 07535 if ((f.frametype == AST_FRAME_VOICE) || 07536 (f.frametype == AST_FRAME_VIDEO) || 07537 (f.frametype == AST_FRAME_IAX)) { 07538 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 07539 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07540 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) { 07541 ast_mutex_unlock(&iaxsl[fr->callno]); 07542 return 1; 07543 } 07544 } 07545 } 07546 07547 if (f.frametype == AST_FRAME_VOICE) { 07548 if (f.subclass != iaxs[fr->callno]->voiceformat) { 07549 iaxs[fr->callno]->voiceformat = f.subclass; 07550 if (option_debug) 07551 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass); 07552 if (iaxs[fr->callno]->owner) { 07553 int orignative; 07554 retryowner: 07555 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07556 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 07557 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner; 07558 } 07559 if (iaxs[fr->callno]) { 07560 if (iaxs[fr->callno]->owner) { 07561 orignative = iaxs[fr->callno]->owner->nativeformats; 07562 iaxs[fr->callno]->owner->nativeformats = f.subclass; 07563 if (iaxs[fr->callno]->owner->readformat) 07564 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07565 iaxs[fr->callno]->owner->nativeformats = orignative; 07566 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07567 } 07568 } else { 07569 if (option_debug) 07570 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); 07571 ast_mutex_unlock(&iaxsl[fr->callno]); 07572 return 1; 07573 } 07574 } 07575 } 07576 } 07577 if (f.frametype == AST_FRAME_VIDEO) { 07578 if (f.subclass != iaxs[fr->callno]->videoformat) { 07579 if (option_debug) 07580 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 07581 iaxs[fr->callno]->videoformat = f.subclass & ~0x1; 07582 } 07583 } 07584 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) { 07585 if (f.subclass == AST_CONTROL_BUSY) { 07586 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY; 07587 } else if (f.subclass == AST_CONTROL_CONGESTION) { 07588 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION; 07589 } 07590 } 07591 if (f.frametype == AST_FRAME_IAX) { 07592 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid); 07593 /* Handle the IAX pseudo frame itself */ 07594 if (option_debug && iaxdebug) 07595 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); 07596 07597 /* Update last ts unless the frame's timestamp originated with us. */ 07598 if (iaxs[fr->callno]->last < fr->ts && 07599 f.subclass != IAX_COMMAND_ACK && 07600 f.subclass != IAX_COMMAND_PONG && 07601 f.subclass != IAX_COMMAND_LAGRP) { 07602 iaxs[fr->callno]->last = fr->ts; 07603 if (option_debug && iaxdebug) 07604 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07605 } 07606 07607 switch(f.subclass) { 07608 case IAX_COMMAND_ACK: 07609 /* Do nothing */ 07610 break; 07611 case IAX_COMMAND_QUELCH: 07612 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07613 /* Generate Manager Hold event, if necessary*/ 07614 if (iaxs[fr->callno]->owner) { 07615 manager_event(EVENT_FLAG_CALL, "Hold", 07616 "Channel: %s\r\n" 07617 "Uniqueid: %s\r\n", 07618 iaxs[fr->callno]->owner->name, 07619 iaxs[fr->callno]->owner->uniqueid); 07620 } 07621 07622 ast_set_flag(iaxs[fr->callno], IAX_QUELCH); 07623 if (ies.musiconhold) { 07624 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07625 const char *mohsuggest = iaxs[fr->callno]->mohsuggest; 07626 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 07627 S_OR(mohsuggest, NULL), 07628 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0); 07629 if (!iaxs[fr->callno]) { 07630 ast_mutex_unlock(&iaxsl[fr->callno]); 07631 return 1; 07632 } 07633 } 07634 } 07635 } 07636 break; 07637 case IAX_COMMAND_UNQUELCH: 07638 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07639 /* Generate Manager Unhold event, if necessary*/ 07640 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { 07641 manager_event(EVENT_FLAG_CALL, "Unhold", 07642 "Channel: %s\r\n" 07643 "Uniqueid: %s\r\n", 07644 iaxs[fr->callno]->owner->name, 07645 iaxs[fr->callno]->owner->uniqueid); 07646 } 07647 07648 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); 07649 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07650 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 07651 if (!iaxs[fr->callno]) { 07652 ast_mutex_unlock(&iaxsl[fr->callno]); 07653 return 1; 07654 } 07655 } 07656 } 07657 break; 07658 case IAX_COMMAND_TXACC: 07659 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 07660 /* Ack the packet with the given timestamp */ 07661 AST_LIST_LOCK(&iaxq.queue); 07662 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07663 /* Cancel any outstanding txcnt's */ 07664 if ((fr->callno == cur->callno) && (cur->transfer)) 07665 cur->retries = -1; 07666 } 07667 AST_LIST_UNLOCK(&iaxq.queue); 07668 memset(&ied1, 0, sizeof(ied1)); 07669 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 07670 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 07671 iaxs[fr->callno]->transferring = TRANSFER_READY; 07672 } 07673 break; 07674 case IAX_COMMAND_NEW: 07675 /* Ignore if it's already up */ 07676 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 07677 break; 07678 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 07679 ast_mutex_unlock(&iaxsl[fr->callno]); 07680 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 07681 ast_mutex_lock(&iaxsl[fr->callno]); 07682 if (!iaxs[fr->callno]) { 07683 ast_mutex_unlock(&iaxsl[fr->callno]); 07684 return 1; 07685 } 07686 } 07687 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 07688 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { 07689 int new_callno; 07690 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 07691 fr->callno = new_callno; 07692 } 07693 /* For security, always ack immediately */ 07694 if (delayreject) 07695 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07696 if (check_access(fr->callno, &sin, &ies)) { 07697 /* They're not allowed on */ 07698 auth_fail(fr->callno, IAX_COMMAND_REJECT); 07699 if (authdebug) 07700 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); 07701 break; 07702 } 07703 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 07704 const char *context, *exten, *cid_num; 07705 07706 context = ast_strdupa(iaxs[fr->callno]->context); 07707 exten = ast_strdupa(iaxs[fr->callno]->exten); 07708 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 07709 07710 /* This might re-enter the IAX code and need the lock */ 07711 ast_mutex_unlock(&iaxsl[fr->callno]); 07712 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 07713 ast_mutex_lock(&iaxsl[fr->callno]); 07714 07715 if (!iaxs[fr->callno]) { 07716 ast_mutex_unlock(&iaxsl[fr->callno]); 07717 return 1; 07718 } 07719 } else 07720 exists = 0; 07721 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 07722 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 07723 memset(&ied0, 0, sizeof(ied0)); 07724 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07725 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07726 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07727 if (!iaxs[fr->callno]) { 07728 ast_mutex_unlock(&iaxsl[fr->callno]); 07729 return 1; 07730 } 07731 if (authdebug) 07732 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); 07733 } else { 07734 /* Select an appropriate format */ 07735 07736 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07737 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07738 using_prefs = "reqonly"; 07739 } else { 07740 using_prefs = "disabled"; 07741 } 07742 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 07743 memset(&pref, 0, sizeof(pref)); 07744 strcpy(caller_pref_buf, "disabled"); 07745 strcpy(host_pref_buf, "disabled"); 07746 } else { 07747 using_prefs = "mine"; 07748 /* If the information elements are in here... use them */ 07749 if (ies.codec_prefs) 07750 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 07751 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07752 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 07753 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07754 pref = iaxs[fr->callno]->rprefs; 07755 using_prefs = "caller"; 07756 } else { 07757 pref = iaxs[fr->callno]->prefs; 07758 } 07759 } else 07760 pref = iaxs[fr->callno]->prefs; 07761 07762 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 07763 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 07764 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 07765 } 07766 if (!format) { 07767 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07768 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 07769 if (!format) { 07770 memset(&ied0, 0, sizeof(ied0)); 07771 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07772 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07773 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07774 if (!iaxs[fr->callno]) { 07775 ast_mutex_unlock(&iaxsl[fr->callno]); 07776 return 1; 07777 } 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 } else { 07785 /* Pick one... */ 07786 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07787 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 07788 format = 0; 07789 } else { 07790 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07791 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 07792 memset(&pref, 0, sizeof(pref)); 07793 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07794 strcpy(caller_pref_buf,"disabled"); 07795 strcpy(host_pref_buf,"disabled"); 07796 } else { 07797 using_prefs = "mine"; 07798 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07799 /* Do the opposite of what we tried above. */ 07800 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07801 pref = iaxs[fr->callno]->prefs; 07802 } else { 07803 pref = iaxs[fr->callno]->rprefs; 07804 using_prefs = "caller"; 07805 } 07806 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 07807 07808 } else /* if no codec_prefs IE do it the old way */ 07809 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07810 } 07811 } 07812 07813 if (!format) { 07814 memset(&ied0, 0, sizeof(ied0)); 07815 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07816 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07817 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07818 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07819 if (!iaxs[fr->callno]) { 07820 ast_mutex_unlock(&iaxsl[fr->callno]); 07821 return 1; 07822 } 07823 if (authdebug) 07824 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); 07825 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07826 break; 07827 } 07828 } 07829 } 07830 if (format) { 07831 /* No authentication required, let them in */ 07832 memset(&ied1, 0, sizeof(ied1)); 07833 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 07834 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 07835 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 07836 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07837 if (option_verbose > 2) 07838 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" 07839 "%srequested format = %s,\n" 07840 "%srequested prefs = %s,\n" 07841 "%sactual format = %s,\n" 07842 "%shost prefs = %s,\n" 07843 "%spriority = %s\n", 07844 ast_inet_ntoa(sin.sin_addr), 07845 VERBOSE_PREFIX_4, 07846 ast_getformatname(iaxs[fr->callno]->peerformat), 07847 VERBOSE_PREFIX_4, 07848 caller_pref_buf, 07849 VERBOSE_PREFIX_4, 07850 ast_getformatname(format), 07851 VERBOSE_PREFIX_4, 07852 host_pref_buf, 07853 VERBOSE_PREFIX_4, 07854 using_prefs); 07855 07856 iaxs[fr->callno]->chosenformat = format; 07857 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07858 } else { 07859 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07860 /* If this is a TBD call, we're ready but now what... */ 07861 if (option_verbose > 2) 07862 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 07863 } 07864 } 07865 } 07866 break; 07867 } 07868 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 07869 merge_encryption(iaxs[fr->callno],ies.encmethods); 07870 else 07871 iaxs[fr->callno]->encmethods = 0; 07872 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 07873 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 07874 if (!iaxs[fr->callno]) { 07875 ast_mutex_unlock(&iaxsl[fr->callno]); 07876 return 1; 07877 } 07878 break; 07879 case IAX_COMMAND_DPREQ: 07880 /* Request status in the dialplan */ 07881 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 07882 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 07883 if (iaxcompat) { 07884 /* Spawn a thread for the lookup */ 07885 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 07886 } else { 07887 /* Just look it up */ 07888 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 07889 } 07890 } 07891 break; 07892 case IAX_COMMAND_HANGUP: 07893 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07894 if (option_debug) 07895 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno); 07896 /* Set hangup cause according to remote */ 07897 if (ies.causecode && iaxs[fr->callno]->owner) 07898 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07899 /* Send ack immediately, before we destroy */ 07900 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07901 iax2_destroy(fr->callno); 07902 break; 07903 case IAX_COMMAND_REJECT: 07904 /* Set hangup cause according to remote */ 07905 if (ies.causecode && iaxs[fr->callno]->owner) 07906 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07907 07908 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07909 if (iaxs[fr->callno]->owner && authdebug) 07910 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 07911 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 07912 ies.cause ? ies.cause : "<Unknown>"); 07913 if (option_debug) 07914 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", 07915 fr->callno); 07916 } 07917 /* Send ack immediately, before we destroy */ 07918 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 07919 fr->ts, NULL, 0, fr->iseqno); 07920 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) 07921 iaxs[fr->callno]->error = EPERM; 07922 iax2_destroy(fr->callno); 07923 break; 07924 case IAX_COMMAND_TRANSFER: 07925 { 07926 struct ast_channel *bridged_chan; 07927 07928 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) { 07929 /* Set BLINDTRANSFER channel variables */ 07930 07931 ast_mutex_unlock(&iaxsl[fr->callno]); 07932 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name); 07933 ast_mutex_lock(&iaxsl[fr->callno]); 07934 if (!iaxs[fr->callno]) { 07935 ast_mutex_unlock(&iaxsl[fr->callno]); 07936 return 1; 07937 } 07938 07939 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name); 07940 if (!strcmp(ies.called_number, ast_parking_ext())) { 07941 struct ast_channel *saved_channel = iaxs[fr->callno]->owner; 07942 ast_mutex_unlock(&iaxsl[fr->callno]); 07943 if (iax_park(bridged_chan, saved_channel)) { 07944 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name); 07945 } else { 07946 ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name); 07947 } 07948 ast_mutex_lock(&iaxsl[fr->callno]); 07949 } else { 07950 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1)) 07951 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 07952 ies.called_number, iaxs[fr->callno]->context); 07953 else 07954 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 07955 ies.called_number, iaxs[fr->callno]->context); 07956 } 07957 } else 07958 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno); 07959 07960 break; 07961 } 07962 case IAX_COMMAND_ACCEPT: 07963 /* Ignore if call is already up or needs authentication or is a TBD */ 07964 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 07965 break; 07966 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07967 /* Send ack immediately, before we destroy */ 07968 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07969 iax2_destroy(fr->callno); 07970 break; 07971 } 07972 if (ies.format) { 07973 iaxs[fr->callno]->peerformat = ies.format; 07974 } else { 07975 if (iaxs[fr->callno]->owner) 07976 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 07977 else 07978 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 07979 } 07980 if (option_verbose > 2) 07981 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)); 07982 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 07983 memset(&ied0, 0, sizeof(ied0)); 07984 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07985 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07986 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07987 if (!iaxs[fr->callno]) { 07988 ast_mutex_unlock(&iaxsl[fr->callno]); 07989 return 1; 07990 } 07991 if (authdebug) 07992 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); 07993 } else { 07994 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07995 if (iaxs[fr->callno]->owner) { 07996 /* Switch us to use a compatible format */ 07997 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 07998 if (option_verbose > 2) 07999 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 08000 retryowner2: 08001 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 08002 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 08003 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2; 08004 } 08005 08006 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 08007 /* Setup read/write formats properly. */ 08008 if (iaxs[fr->callno]->owner->writeformat) 08009 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 08010 if (iaxs[fr->callno]->owner->readformat) 08011 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 08012 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 08013 } 08014 } 08015 } 08016 if (iaxs[fr->callno]) { 08017 ast_mutex_lock(&dpcache_lock); 08018 dp = iaxs[fr->callno]->dpentries; 08019 while(dp) { 08020 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) { 08021 iax2_dprequest(dp, fr->callno); 08022 } 08023 dp = dp->peer; 08024 } 08025 ast_mutex_unlock(&dpcache_lock); 08026 } 08027 break; 08028 case IAX_COMMAND_POKE: 08029 /* Send back a pong packet with the original timestamp */ 08030 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 08031 if (!iaxs[fr->callno]) { 08032 ast_mutex_unlock(&iaxsl[fr->callno]); 08033 return 1; 08034 } 08035 break; 08036 case IAX_COMMAND_PING: 08037 { 08038 struct iax_ie_data pingied; 08039 construct_rr(iaxs[fr->callno], &pingied); 08040 /* Send back a pong packet with the original timestamp */ 08041 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 08042 } 08043 break; 08044 case IAX_COMMAND_PONG: 08045 /* Calculate ping time */ 08046 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 08047 /* save RR info */ 08048 save_rr(fr, &ies); 08049 08050 if (iaxs[fr->callno]->peerpoke) { 08051 peer = iaxs[fr->callno]->peerpoke; 08052 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 08053 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 08054 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 08055 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 08056 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 08057 } 08058 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 08059 if (iaxs[fr->callno]->pingtime > peer->maxms) { 08060 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 08061 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 08062 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 08063 } 08064 } 08065 peer->lastms = iaxs[fr->callno]->pingtime; 08066 if (peer->smoothing && (peer->lastms > -1)) 08067 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 08068 else if (peer->smoothing && peer->lastms < 0) 08069 peer->historicms = (0 + peer->historicms) / 2; 08070 else 08071 peer->historicms = iaxs[fr->callno]->pingtime; 08072 08073 /* Remove scheduled iax2_poke_noanswer */ 08074 if (peer->pokeexpire > -1) { 08075 if (!ast_sched_del(sched, peer->pokeexpire)) { 08076 peer_unref(peer); 08077 peer->pokeexpire = -1; 08078 } 08079 } 08080 /* Schedule the next cycle */ 08081 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 08082 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 08083 else 08084 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 08085 if (peer->pokeexpire == -1) 08086 peer_unref(peer); 08087 /* and finally send the ack */ 08088 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08089 /* And wrap up the qualify call */ 08090 iax2_destroy(fr->callno); 08091 peer->callno = 0; 08092 if (option_debug) 08093 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 08094 } 08095 break; 08096 case IAX_COMMAND_LAGRQ: 08097 case IAX_COMMAND_LAGRP: 08098 f.src = "LAGRQ"; 08099 f.mallocd = 0; 08100 f.offset = 0; 08101 f.samples = 0; 08102 iax_frame_wrap(fr, &f); 08103 if(f.subclass == IAX_COMMAND_LAGRQ) { 08104 /* Received a LAGRQ - echo back a LAGRP */ 08105 fr->af.subclass = IAX_COMMAND_LAGRP; 08106 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 08107 } else { 08108 /* Received LAGRP in response to our LAGRQ */ 08109 unsigned int ts; 08110 /* This is a reply we've been given, actually measure the difference */ 08111 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 08112 iaxs[fr->callno]->lag = ts - fr->ts; 08113 if (option_debug && iaxdebug) 08114 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", 08115 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 08116 } 08117 break; 08118 case IAX_COMMAND_AUTHREQ: 08119 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 08120 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>"); 08121 break; 08122 } 08123 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 08124 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 08125 .subclass = AST_CONTROL_HANGUP, 08126 }; 08127 ast_log(LOG_WARNING, 08128 "I don't know how to authenticate %s to %s\n", 08129 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 08130 iax2_queue_frame(fr->callno, &hangup_fr); 08131 } 08132 if (!iaxs[fr->callno]) { 08133 ast_mutex_unlock(&iaxsl[fr->callno]); 08134 return 1; 08135 } 08136 break; 08137 case IAX_COMMAND_AUTHREP: 08138 /* For security, always ack immediately */ 08139 if (delayreject) 08140 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08141 /* Ignore once we've started */ 08142 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 08143 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>"); 08144 break; 08145 } 08146 if (authenticate_verify(iaxs[fr->callno], &ies)) { 08147 if (authdebug) 08148 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); 08149 memset(&ied0, 0, sizeof(ied0)); 08150 auth_fail(fr->callno, IAX_COMMAND_REJECT); 08151 break; 08152 } 08153 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 08154 /* This might re-enter the IAX code and need the lock */ 08155 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 08156 } else 08157 exists = 0; 08158 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 08159 if (authdebug) 08160 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); 08161 memset(&ied0, 0, sizeof(ied0)); 08162 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 08163 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 08164 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08165 if (!iaxs[fr->callno]) { 08166 ast_mutex_unlock(&iaxsl[fr->callno]); 08167 return 1; 08168 } 08169 } else { 08170 /* Select an appropriate format */ 08171 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 08172 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08173 using_prefs = "reqonly"; 08174 } else { 08175 using_prefs = "disabled"; 08176 } 08177 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 08178 memset(&pref, 0, sizeof(pref)); 08179 strcpy(caller_pref_buf, "disabled"); 08180 strcpy(host_pref_buf, "disabled"); 08181 } else { 08182 using_prefs = "mine"; 08183 if (ies.codec_prefs) 08184 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 08185 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 08186 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 08187 pref = iaxs[fr->callno]->rprefs; 08188 using_prefs = "caller"; 08189 } else { 08190 pref = iaxs[fr->callno]->prefs; 08191 } 08192 } else /* if no codec_prefs IE do it the old way */ 08193 pref = iaxs[fr->callno]->prefs; 08194 08195 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 08196 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 08197 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 08198 } 08199 if (!format) { 08200 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08201 if (option_debug) 08202 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); 08203 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 08204 } 08205 if (!format) { 08206 if (authdebug) { 08207 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 08208 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); 08209 else 08210 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); 08211 } 08212 memset(&ied0, 0, sizeof(ied0)); 08213 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 08214 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 08215 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08216 if (!iaxs[fr->callno]) { 08217 ast_mutex_unlock(&iaxsl[fr->callno]); 08218 return 1; 08219 } 08220 } else { 08221 /* Pick one... */ 08222 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08223 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 08224 format = 0; 08225 } else { 08226 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 08227 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 08228 memset(&pref, 0, sizeof(pref)); 08229 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 08230 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08231 strcpy(caller_pref_buf,"disabled"); 08232 strcpy(host_pref_buf,"disabled"); 08233 } else { 08234 using_prefs = "mine"; 08235 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 08236 /* Do the opposite of what we tried above. */ 08237 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 08238 pref = iaxs[fr->callno]->prefs; 08239 } else { 08240 pref = iaxs[fr->callno]->rprefs; 08241 using_prefs = "caller"; 08242 } 08243 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 08244 } else /* if no codec_prefs IE do it the old way */ 08245 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08246 } 08247 } 08248 if (!format) { 08249 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08250 if (authdebug) { 08251 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 08252 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); 08253 else 08254 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); 08255 } 08256 memset(&ied0, 0, sizeof(ied0)); 08257 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 08258 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 08259 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08260 if (!iaxs[fr->callno]) { 08261 ast_mutex_unlock(&iaxsl[fr->callno]); 08262 return 1; 08263 } 08264 } 08265 } 08266 } 08267 if (format) { 08268 /* Authentication received */ 08269 memset(&ied1, 0, sizeof(ied1)); 08270 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 08271 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 08272 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 08273 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08274 if (option_verbose > 2) 08275 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" 08276 "%srequested format = %s,\n" 08277 "%srequested prefs = %s,\n" 08278 "%sactual format = %s,\n" 08279 "%shost prefs = %s,\n" 08280 "%spriority = %s\n", 08281 ast_inet_ntoa(sin.sin_addr), 08282 VERBOSE_PREFIX_4, 08283 ast_getformatname(iaxs[fr->callno]->peerformat), 08284 VERBOSE_PREFIX_4, 08285 caller_pref_buf, 08286 VERBOSE_PREFIX_4, 08287 ast_getformatname(format), 08288 VERBOSE_PREFIX_4, 08289 host_pref_buf, 08290 VERBOSE_PREFIX_4, 08291 using_prefs); 08292 08293 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08294 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 08295 iax2_destroy(fr->callno); 08296 } else { 08297 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 08298 /* If this is a TBD call, we're ready but now what... */ 08299 if (option_verbose > 2) 08300 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 08301 } 08302 } 08303 } 08304 break; 08305 case IAX_COMMAND_DIAL: 08306 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 08307 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 08308 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 08309 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 08310 if (authdebug) 08311 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); 08312 memset(&ied0, 0, sizeof(ied0)); 08313 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 08314 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 08315 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08316 if (!iaxs[fr->callno]) { 08317 ast_mutex_unlock(&iaxsl[fr->callno]); 08318 return 1; 08319 } 08320 } else { 08321 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08322 if (option_verbose > 2) 08323 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat); 08324 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08325 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 08326 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) 08327 iax2_destroy(fr->callno); 08328 } 08329 } 08330 break; 08331 case IAX_COMMAND_INVAL: 08332 iaxs[fr->callno]->error = ENOTCONN; 08333 if (option_debug) 08334 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno); 08335 iax2_destroy(fr->callno); 08336 if (option_debug) 08337 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno); 08338 break; 08339 case IAX_COMMAND_VNAK: 08340 if (option_debug) 08341 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); 08342 /* Force retransmission */ 08343 vnak_retransmit(fr->callno, fr->iseqno); 08344 break; 08345 case IAX_COMMAND_REGREQ: 08346 case IAX_COMMAND_REGREL: 08347 /* For security, always ack immediately */ 08348 if (delayreject) 08349 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08350 if (register_verify(fr->callno, &sin, &ies)) { 08351 if (!iaxs[fr->callno]) { 08352 ast_mutex_unlock(&iaxsl[fr->callno]); 08353 return 1; 08354 } 08355 /* Send delayed failure */ 08356 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 08357 break; 08358 } 08359 if (!iaxs[fr->callno]) { 08360 ast_mutex_unlock(&iaxsl[fr->callno]); 08361 return 1; 08362 } 08363 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 08364 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) { 08365 if (f.subclass == IAX_COMMAND_REGREL) 08366 memset(&sin, 0, sizeof(sin)); 08367 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) 08368 ast_log(LOG_WARNING, "Registry error\n"); 08369 if (!iaxs[fr->callno]) { 08370 ast_mutex_unlock(&iaxsl[fr->callno]); 08371 return 1; 08372 } 08373 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 08374 ast_mutex_unlock(&iaxsl[fr->callno]); 08375 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 08376 ast_mutex_lock(&iaxsl[fr->callno]); 08377 if (!iaxs[fr->callno]) { 08378 ast_mutex_unlock(&iaxsl[fr->callno]); 08379 return 1; 08380 } 08381 } 08382 break; 08383 } 08384 registry_authrequest(fr->callno); 08385 if (!iaxs[fr->callno]) { 08386 ast_mutex_unlock(&iaxsl[fr->callno]); 08387 return 1; 08388 } 08389 break; 08390 case IAX_COMMAND_REGACK: 08391 if (iax2_ack_registry(&ies, &sin, fr->callno)) 08392 ast_log(LOG_WARNING, "Registration failure\n"); 08393 /* Send ack immediately, before we destroy */ 08394 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08395 iax2_destroy(fr->callno); 08396 break; 08397 case IAX_COMMAND_REGREJ: 08398 if (iaxs[fr->callno]->reg) { 08399 if (authdebug) { 08400 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)); 08401 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>"); 08402 } 08403 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 08404 } 08405 /* Send ack immediately, before we destroy */ 08406 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08407 iax2_destroy(fr->callno); 08408 break; 08409 case IAX_COMMAND_REGAUTH: 08410 /* Authentication request */ 08411 if (registry_rerequest(&ies, fr->callno, &sin)) { 08412 memset(&ied0, 0, sizeof(ied0)); 08413 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 08414 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 08415 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08416 if (!iaxs[fr->callno]) { 08417 ast_mutex_unlock(&iaxsl[fr->callno]); 08418 return 1; 08419 } 08420 } 08421 break; 08422 case IAX_COMMAND_TXREJ: 08423 iaxs[fr->callno]->transferring = 0; 08424 if (option_verbose > 2) 08425 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 08426 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 08427 if (iaxs[fr->callno]->bridgecallno) { 08428 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 08429 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 08430 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 08431 } 08432 } 08433 break; 08434 case IAX_COMMAND_TXREADY: 08435 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 08436 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 08437 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 08438 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 08439 else 08440 iaxs[fr->callno]->transferring = TRANSFER_READY; 08441 if (option_verbose > 2) 08442 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 08443 if (iaxs[fr->callno]->bridgecallno) { 08444 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 08445 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 08446 /* They're both ready, now release them. */ 08447 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 08448 if (option_verbose > 2) 08449 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 08450 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 08451 08452 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 08453 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 08454 08455 memset(&ied0, 0, sizeof(ied0)); 08456 memset(&ied1, 0, sizeof(ied1)); 08457 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 08458 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 08459 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 08460 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 08461 } else { 08462 if (option_verbose > 2) 08463 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 08464 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 08465 08466 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 08467 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 08468 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 08469 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 08470 08471 /* Stop doing lag & ping requests */ 08472 stop_stuff(fr->callno); 08473 stop_stuff(iaxs[fr->callno]->bridgecallno); 08474 08475 memset(&ied0, 0, sizeof(ied0)); 08476 memset(&ied1, 0, sizeof(ied1)); 08477 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 08478 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 08479 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 08480 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 08481 } 08482 08483 } 08484 } 08485 } 08486 break; 08487 case IAX_COMMAND_TXREQ: 08488 try_transfer(iaxs[fr->callno], &ies); 08489 break; 08490 case IAX_COMMAND_TXCNT: 08491 if (iaxs[fr->callno]->transferring) 08492 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 08493 break; 08494 case IAX_COMMAND_TXREL: 08495 /* Send ack immediately, rather than waiting until we've changed addresses */ 08496 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08497 complete_transfer(fr->callno, &ies); 08498 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 08499 break; 08500 case IAX_COMMAND_TXMEDIA: 08501 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 08502 AST_LIST_LOCK(&iaxq.queue); 08503 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 08504 /* Cancel any outstanding frames and start anew */ 08505 if ((fr->callno == cur->callno) && (cur->transfer)) { 08506 cur->retries = -1; 08507 } 08508 } 08509 AST_LIST_UNLOCK(&iaxq.queue); 08510 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 08511 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 08512 } 08513 break; 08514 case IAX_COMMAND_DPREP: 08515 complete_dpreply(iaxs[fr->callno], &ies); 08516 break; 08517 case IAX_COMMAND_UNSUPPORT: 08518 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 08519 break; 08520 case IAX_COMMAND_FWDOWNL: 08521 /* Firmware download */ 08522 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 08523 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 08524 break; 08525 } 08526 memset(&ied0, 0, sizeof(ied0)); 08527 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 08528 if (res < 0) 08529 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08530 else if (res > 0) 08531 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08532 else 08533 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08534 if (!iaxs[fr->callno]) { 08535 ast_mutex_unlock(&iaxsl[fr->callno]); 08536 return 1; 08537 } 08538 break; 08539 default: 08540 if (option_debug) 08541 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); 08542 memset(&ied0, 0, sizeof(ied0)); 08543 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 08544 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 08545 } 08546 /* Don't actually pass these frames along */ 08547 if ((f.subclass != IAX_COMMAND_ACK) && 08548 (f.subclass != IAX_COMMAND_TXCNT) && 08549 (f.subclass != IAX_COMMAND_TXACC) && 08550 (f.subclass != IAX_COMMAND_INVAL) && 08551 (f.subclass != IAX_COMMAND_VNAK)) { 08552 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08553 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08554 } 08555 ast_mutex_unlock(&iaxsl[fr->callno]); 08556 return 1; 08557 } 08558 /* Unless this is an ACK or INVAL frame, ack it */ 08559 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08560 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08561 } else if (minivid) { 08562 f.frametype = AST_FRAME_VIDEO; 08563 if (iaxs[fr->callno]->videoformat > 0) 08564 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 08565 else { 08566 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n"); 08567 iax2_vnak(fr->callno); 08568 ast_mutex_unlock(&iaxsl[fr->callno]); 08569 return 1; 08570 } 08571 f.datalen = res - sizeof(*vh); 08572 if (f.datalen) 08573 f.data = thread->buf + sizeof(*vh); 08574 else 08575 f.data = NULL; 08576 #ifdef IAXTESTS 08577 if (test_resync) { 08578 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 08579 } else 08580 #endif /* IAXTESTS */ 08581 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 08582 } else { 08583 /* A mini frame */ 08584 f.frametype = AST_FRAME_VOICE; 08585 if (iaxs[fr->callno]->voiceformat > 0) 08586 f.subclass = iaxs[fr->callno]->voiceformat; 08587 else { 08588 if (option_debug) 08589 ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n"); 08590 iax2_vnak(fr->callno); 08591 ast_mutex_unlock(&iaxsl[fr->callno]); 08592 return 1; 08593 } 08594 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 08595 if (f.datalen < 0) { 08596 ast_log(LOG_WARNING, "Datalen < 0?\n"); 08597 ast_mutex_unlock(&iaxsl[fr->callno]); 08598 return 1; 08599 } 08600 if (f.datalen) 08601 f.data = thread->buf + sizeof(*mh); 08602 else 08603 f.data = NULL; 08604 #ifdef IAXTESTS 08605 if (test_resync) { 08606 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 08607 } else 08608 #endif /* IAXTESTS */ 08609 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 08610 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 08611 } 08612 /* Don't pass any packets until we're started */ 08613 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 08614 ast_mutex_unlock(&iaxsl[fr->callno]); 08615 return 1; 08616 } 08617 /* Common things */ 08618 f.src = "IAX2"; 08619 f.mallocd = 0; 08620 f.offset = 0; 08621 f.len = 0; 08622 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 08623 f.samples = ast_codec_get_samples(&f); 08624 /* We need to byteswap incoming slinear samples from network byte order */ 08625 if (f.subclass == AST_FORMAT_SLINEAR) 08626 ast_frame_byteswap_be(&f); 08627 } else 08628 f.samples = 0; 08629 iax_frame_wrap(fr, &f); 08630 08631 /* If this is our most recent packet, use it as our basis for timestamping */ 08632 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08633 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 08634 fr->outoforder = 0; 08635 } else { 08636 if (option_debug && iaxdebug && iaxs[fr->callno]) 08637 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); 08638 fr->outoforder = -1; 08639 } 08640 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 08641 duped_fr = iaxfrdup2(fr); 08642 if (duped_fr) { 08643 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 08644 } 08645 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08646 iaxs[fr->callno]->last = fr->ts; 08647 #if 1 08648 if (option_debug && iaxdebug) 08649 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 08650 #endif 08651 } 08652 08653 /* Always run again */ 08654 ast_mutex_unlock(&iaxsl[fr->callno]); 08655 return 1; 08656 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 7002 of file chan_iax2.c.
References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_random(), iax2_thread::callno, ast_iax2_full_hdr::csub, defer_full_frame(), errno, iax2_thread::ffinfo, find_idle_thread(), handle_error(), IAX_FLAG_FULL, IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, inaddrcmp(), iax2_thread::list, LOG_WARNING, option_debug, ast_iax2_full_hdr::scallno, signal_condition(), iax2_thread::sin, t, thread, and ast_iax2_full_hdr::type.
Referenced by network_thread(), peer_set_srcaddr(), and set_config().
07003 { 07004 struct iax2_thread *thread; 07005 socklen_t len; 07006 time_t t; 07007 static time_t last_errtime = 0; 07008 struct ast_iax2_full_hdr *fh; 07009 07010 if (!(thread = find_idle_thread())) { 07011 time(&t); 07012 if (t != last_errtime && option_debug) 07013 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n"); 07014 last_errtime = t; 07015 usleep(1); 07016 return 1; 07017 } 07018 07019 len = sizeof(thread->iosin); 07020 thread->iofd = fd; 07021 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 07022 thread->buf_size = sizeof(thread->readbuf); 07023 thread->buf = thread->readbuf; 07024 if (thread->buf_len < 0) { 07025 if (errno != ECONNREFUSED && errno != EAGAIN) 07026 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 07027 handle_error(); 07028 thread->iostate = IAX_IOSTATE_IDLE; 07029 signal_condition(&thread->lock, &thread->cond); 07030 return 1; 07031 } 07032 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 07033 thread->iostate = IAX_IOSTATE_IDLE; 07034 signal_condition(&thread->lock, &thread->cond); 07035 return 1; 07036 } 07037 07038 /* Determine if this frame is a full frame; if so, and any thread is currently 07039 processing a full frame for the same callno from this peer, then drop this 07040 frame (and the peer will retransmit it) */ 07041 fh = (struct ast_iax2_full_hdr *) thread->buf; 07042 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 07043 struct iax2_thread *cur = NULL; 07044 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 07045 07046 AST_LIST_LOCK(&active_list); 07047 AST_LIST_TRAVERSE(&active_list, cur, list) { 07048 if ((cur->ffinfo.callno == callno) && 07049 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 07050 break; 07051 } 07052 if (cur) { 07053 /* we found another thread processing a full frame for this call, 07054 so queue it up for processing later. */ 07055 defer_full_frame(thread, cur); 07056 AST_LIST_UNLOCK(&active_list); 07057 thread->iostate = IAX_IOSTATE_IDLE; 07058 signal_condition(&thread->lock, &thread->cond); 07059 return 1; 07060 } else { 07061 /* this thread is going to process this frame, so mark it */ 07062 thread->ffinfo.callno = callno; 07063 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 07064 thread->ffinfo.type = fh->type; 07065 thread->ffinfo.csub = fh->csub; 07066 } 07067 AST_LIST_UNLOCK(&active_list); 07068 } 07069 07070 /* Mark as ready and send on its way */ 07071 thread->iostate = IAX_IOSTATE_READY; 07072 #ifdef DEBUG_SCHED_MULTITHREAD 07073 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 07074 #endif 07075 signal_condition(&thread->lock, &thread->cond); 07076 07077 return 1; 07078 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 6789 of file chan_iax2.c.
References ast_calloc, ast_copy_string(), ast_log(), ast_pthread_create, ast_strdup, dp_lookup_thread(), and LOG_WARNING.
Referenced by socket_process().
06790 { 06791 pthread_t newthread; 06792 struct dpreq_data *dpr; 06793 pthread_attr_t attr; 06794 06795 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 06796 return; 06797 06798 pthread_attr_init(&attr); 06799 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06800 06801 dpr->callno = callno; 06802 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 06803 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 06804 if (callerid) 06805 dpr->callerid = ast_strdup(callerid); 06806 if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) { 06807 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 06808 } 06809 06810 pthread_attr_destroy(&attr); 06811 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 9258 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, iax_frame::list, LOG_WARNING, network_thread(), option_verbose, sched_thread(), thread, and VERBOSE_PREFIX_2.
Referenced by load_module().
09259 { 09260 pthread_attr_t attr; 09261 int threadcount = 0; 09262 int x; 09263 for (x = 0; x < iaxthreadcount; x++) { 09264 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread)); 09265 if (thread) { 09266 thread->type = IAX_TYPE_POOL; 09267 thread->threadnum = ++threadcount; 09268 ast_mutex_init(&thread->lock); 09269 ast_cond_init(&thread->cond, NULL); 09270 pthread_attr_init(&attr); 09271 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 09272 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 09273 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 09274 free(thread); 09275 thread = NULL; 09276 } 09277 AST_LIST_LOCK(&idle_list); 09278 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 09279 AST_LIST_UNLOCK(&idle_list); 09280 } 09281 } 09282 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL); 09283 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 09284 if (option_verbose > 1) 09285 ast_verbose(VERBOSE_PREFIX_2 "%d helper threads started\n", threadcount); 09286 return 0; 09287 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 6471 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
06472 { 06473 iax2_destroy_helper(iaxs[callno]); 06474 }
static void store_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1248 of file chan_iax2.c.
References ast_log(), iax_peercallno_pvts, LOG_ERROR, and chan_iax2_pvt::peercallno.
Referenced by __find_callno(), complete_transfer(), and socket_process().
01249 { 01250 if (!pvt->peercallno) { 01251 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01252 return; 01253 } 01254 01255 ao2_link(iax_peercallno_pvts, pvt); 01256 }
static int timing_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6658 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_inet_ntoa(), AST_IO_PRI, ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), free, iax2_trunk_expired(), iax2_trunk_peer::lock, LOG_WARNING, MAX_TRUNKDATA, iax2_trunk_peer::next, option_debug, send_trunk(), tpeerlock, tpeers, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.
Referenced by network_thread().
06659 { 06660 char buf[1024]; 06661 int res; 06662 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL; 06663 int processed = 0; 06664 int totalcalls = 0; 06665 #ifdef DAHDI_TIMERACK 06666 int x = 1; 06667 #endif 06668 struct timeval now; 06669 if (iaxtrunkdebug) 06670 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA); 06671 gettimeofday(&now, NULL); 06672 if (events & AST_IO_PRI) { 06673 #ifdef DAHDI_TIMERACK 06674 /* Great, this is a timing interface, just call the ioctl */ 06675 if (ioctl(fd, DAHDI_TIMERACK, &x)) { 06676 ast_log(LOG_WARNING, "Unable to acknowledge timer. IAX trunking will fail!\n"); 06677 usleep(1); 06678 return -1; 06679 } 06680 #endif 06681 } else { 06682 /* Read and ignore from the pseudo channel for timing */ 06683 res = read(fd, buf, sizeof(buf)); 06684 if (res < 1) { 06685 ast_log(LOG_WARNING, "Unable to read from timing fd\n"); 06686 return 1; 06687 } 06688 } 06689 /* For each peer that supports trunking... */ 06690 ast_mutex_lock(&tpeerlock); 06691 tpeer = tpeers; 06692 while(tpeer) { 06693 processed++; 06694 res = 0; 06695 ast_mutex_lock(&tpeer->lock); 06696 /* We can drop a single tpeer per pass. That makes all this logic 06697 substantially easier */ 06698 if (!drop && iax2_trunk_expired(tpeer, &now)) { 06699 /* Take it out of the list, but don't free it yet, because it 06700 could be in use */ 06701 if (prev) 06702 prev->next = tpeer->next; 06703 else 06704 tpeers = tpeer->next; 06705 drop = tpeer; 06706 } else { 06707 res = send_trunk(tpeer, &now); 06708 if (iaxtrunkdebug) 06709 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); 06710 } 06711 totalcalls += res; 06712 res = 0; 06713 ast_mutex_unlock(&tpeer->lock); 06714 prev = tpeer; 06715 tpeer = tpeer->next; 06716 } 06717 ast_mutex_unlock(&tpeerlock); 06718 if (drop) { 06719 ast_mutex_lock(&drop->lock); 06720 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 06721 because by the time they could get tpeerlock, we've already grabbed it */ 06722 if (option_debug) 06723 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 06724 if (drop->trunkdata) { 06725 free(drop->trunkdata); 06726 drop->trunkdata = NULL; 06727 } 06728 ast_mutex_unlock(&drop->lock); 06729 ast_mutex_destroy(&drop->lock); 06730 free(drop); 06731 06732 } 06733 if (iaxtrunkdebug) 06734 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 06735 iaxtrunkdebug =0; 06736 return 1; 06737 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 2129 of file chan_iax2.c.
References ast_log(), errno, f, handle_error(), LOG_DEBUG, and option_debug.
Referenced by send_trunk().
02130 { 02131 int res; 02132 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 02133 sizeof(*sin)); 02134 if (res < 0) { 02135 if (option_debug) 02136 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 02137 handle_error(); 02138 } else 02139 res = 0; 02140 return res; 02141 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 1817 of file chan_iax2.c.
References ast_calloc, ast_log(), ast_random(), ast_strlen_zero(), ast_iax2_firmware_header::chksum, ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, iax_firmware::dead, ast_iax2_firmware_header::devname, errno, iax_firmware::fd, iax_firmware::fwh, IAX_FIRMWARE_MAGIC, last, 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().
01818 { 01819 struct stat stbuf; 01820 struct iax_firmware *cur; 01821 int ifd; 01822 int fd; 01823 int res; 01824 01825 struct ast_iax2_firmware_header *fwh, fwh2; 01826 struct MD5Context md5; 01827 unsigned char sum[16]; 01828 unsigned char buf[1024]; 01829 int len, chunk; 01830 char *s2; 01831 char *last; 01832 s2 = alloca(strlen(s) + 100); 01833 if (!s2) { 01834 ast_log(LOG_WARNING, "Alloca failed!\n"); 01835 return -1; 01836 } 01837 last = strrchr(s, '/'); 01838 if (last) 01839 last++; 01840 else 01841 last = s; 01842 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 01843 res = stat(s, &stbuf); 01844 if (res < 0) { 01845 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 01846 return -1; 01847 } 01848 /* Make sure it's not a directory */ 01849 if (S_ISDIR(stbuf.st_mode)) 01850 return -1; 01851 ifd = open(s, O_RDONLY); 01852 if (ifd < 0) { 01853 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 01854 return -1; 01855 } 01856 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600); 01857 if (fd < 0) { 01858 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 01859 close(ifd); 01860 return -1; 01861 } 01862 /* Unlink our newly created file */ 01863 unlink(s2); 01864 01865 /* Now copy the firmware into it */ 01866 len = stbuf.st_size; 01867 while(len) { 01868 chunk = len; 01869 if (chunk > sizeof(buf)) 01870 chunk = sizeof(buf); 01871 res = read(ifd, buf, chunk); 01872 if (res != chunk) { 01873 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01874 close(ifd); 01875 close(fd); 01876 return -1; 01877 } 01878 res = write(fd, buf, chunk); 01879 if (res != chunk) { 01880 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01881 close(ifd); 01882 close(fd); 01883 return -1; 01884 } 01885 len -= chunk; 01886 } 01887 close(ifd); 01888 /* Return to the beginning */ 01889 lseek(fd, 0, SEEK_SET); 01890 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 01891 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 01892 close(fd); 01893 return -1; 01894 } 01895 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 01896 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 01897 close(fd); 01898 return -1; 01899 } 01900 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 01901 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 01902 close(fd); 01903 return -1; 01904 } 01905 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 01906 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 01907 close(fd); 01908 return -1; 01909 } 01910 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 01911 if (fwh == (void *) -1) { 01912 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 01913 close(fd); 01914 return -1; 01915 } 01916 MD5Init(&md5); 01917 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 01918 MD5Final(sum, &md5); 01919 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 01920 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 01921 munmap((void*)fwh, stbuf.st_size); 01922 close(fd); 01923 return -1; 01924 } 01925 cur = waresl.wares; 01926 while(cur) { 01927 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 01928 /* Found a candidate */ 01929 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 01930 /* The version we have on loaded is older, load this one instead */ 01931 break; 01932 /* This version is no newer than what we have. Don't worry about it. 01933 We'll consider it a proper load anyhow though */ 01934 munmap((void*)fwh, stbuf.st_size); 01935 close(fd); 01936 return 0; 01937 } 01938 cur = cur->next; 01939 } 01940 if (!cur) { 01941 /* Allocate a new one and link it */ 01942 if ((cur = ast_calloc(1, sizeof(*cur)))) { 01943 cur->fd = -1; 01944 cur->next = waresl.wares; 01945 waresl.wares = cur; 01946 } 01947 } 01948 if (cur) { 01949 if (cur->fwh) { 01950 munmap((void*)cur->fwh, cur->mmaplen); 01951 } 01952 if (cur->fd > -1) 01953 close(cur->fd); 01954 cur->fwh = fwh; 01955 cur->fd = fd; 01956 cur->mmaplen = stbuf.st_size; 01957 cur->dead = 0; 01958 } 01959 return 0; 01960 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5863 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().
05864 { 05865 int newcall = 0; 05866 char newip[256]; 05867 struct iax_ie_data ied; 05868 struct sockaddr_in new; 05869 05870 05871 memset(&ied, 0, sizeof(ied)); 05872 if (ies->apparent_addr) 05873 bcopy(ies->apparent_addr, &new, sizeof(new)); 05874 if (ies->callno) 05875 newcall = ies->callno; 05876 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 05877 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05878 return -1; 05879 } 05880 pvt->transfercallno = newcall; 05881 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 05882 inet_aton(newip, &pvt->transfer.sin_addr); 05883 pvt->transfer.sin_family = AF_INET; 05884 pvt->transferring = TRANSFER_BEGIN; 05885 pvt->transferid = ies->transferid; 05886 if (ies->transferid) 05887 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 05888 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 05889 return 0; 05890 }
static int uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1093 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), and socket_process().
01094 { 01095 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01096 if (csub & IAX_FLAG_SC_LOG) { 01097 /* special case for 'compressed' -1 */ 01098 if (csub == 0xff) 01099 return -1; 01100 else 01101 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01102 } 01103 else 01104 return csub; 01105 }
static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 6139 of file chan_iax2.c.
References ao2_unlink(), ast_sched_del(), iax2_peer::expire, peer_unref(), iax2_peer::pokeexpire, and sched.
Referenced by __expire_registry(), build_peer(), and prune_peers().
06140 { 06141 if (peer->expire > -1) { 06142 if (!ast_sched_del(sched, peer->expire)) { 06143 peer->expire = -1; 06144 peer_unref(peer); 06145 } 06146 } 06147 06148 if (peer->pokeexpire > -1) { 06149 if (!ast_sched_del(sched, peer->pokeexpire)) { 06150 peer->pokeexpire = -1; 06151 peer_unref(peer); 06152 } 06153 } 06154 06155 ao2_unlink(peers, peer); 06156 }
static int unload_module | ( | void | ) | [static] |
Definition at line 11184 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), and iaxpeer_function.
11185 { 11186 ast_custom_function_unregister(&iaxpeer_function); 11187 return __unload_module(); 11188 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3590 of file chan_iax2.c.
References ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
03591 { 03592 ast_mutex_unlock(&iaxsl[callno1]); 03593 ast_mutex_unlock(&iaxsl[callno0]); 03594 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2563 of file chan_iax2.c.
References iax_frame::af, AST_FRAME_VIDEO, ast_log(), iax_frame::callno, ast_frame::frametype, iaxs, chan_iax2_pvt::last, LOG_DEBUG, option_debug, and iax_frame::ts.
Referenced by schedule_delivery().
02564 { 02565 /* Video mini frames only encode the lower 15 bits of the session 02566 * timestamp, but other frame types (e.g. audio) encode 16 bits. */ 02567 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16; 02568 const int lower_mask = (1 << ts_shift) - 1; 02569 const int upper_mask = ~lower_mask; 02570 const int last_upper = iaxs[fr->callno]->last & upper_mask; 02571 02572 if ( (fr->ts & upper_mask) == last_upper ) { 02573 const int x = fr->ts - iaxs[fr->callno]->last; 02574 const int threshold = (ts_shift == 15) ? 25000 : 50000; 02575 02576 if (x < -threshold) { 02577 /* Sudden big jump backwards in timestamp: 02578 What likely happened here is that miniframe timestamp has circled but we haven't 02579 gotten the update from the main packet. We'll just pretend that we did, and 02580 update the timestamp appropriately. */ 02581 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask); 02582 if (option_debug && iaxdebug) 02583 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n"); 02584 } else if (x > threshold) { 02585 /* Sudden apparent big jump forwards in timestamp: 02586 What's likely happened is this is an old miniframe belonging to the previous 02587 top 15 or 16-bit timestamp that has turned up out of order. 02588 Adjust the timestamp appropriately. */ 02589 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask); 02590 if (option_debug && iaxdebug) 02591 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n"); 02592 } 02593 } 02594 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2598 of file chan_iax2.c.
References AST_SCHED_DEL, ast_tvdiff_ms(), ast_tvnow(), chan_iax2_pvt::callno, CALLNO_TO_PTR, get_from_jb(), iax2_sched_add(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, chan_iax2_pvt::rxcore, and sched.
Referenced by __get_from_jb(), and schedule_delivery().
02599 { 02600 int when; 02601 02602 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 02603 02604 when = jb_next(pvt->jb) - when; 02605 02606 AST_SCHED_DEL(sched, pvt->jbid); 02607 02608 if(when <= 0) { 02609 /* XXX should really just empty until when > 0.. */ 02610 when = 1; 02611 } 02612 02613 pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno)); 02614 }
static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 1477 of file chan_iax2.c.
References ast_log(), LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by __find_callno(), and make_trunk().
01478 { 01479 int max = 1; 01480 int x; 01481 /* XXX Prolly don't need locks here XXX */ 01482 for (x=1;x<TRUNK_CALL_START - 1; x++) { 01483 if (iaxs[x]) 01484 max = x + 1; 01485 } 01486 maxnontrunkcall = max; 01487 if (option_debug && iaxdebug) 01488 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max); 01489 }
static void update_max_trunk | ( | void | ) | [static] |
Definition at line 1268 of file chan_iax2.c.
References ARRAY_LEN, ast_log(), LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by iax2_destroy(), and make_trunk().
01269 { 01270 int max = TRUNK_CALL_START; 01271 int x; 01272 01273 /* XXX Prolly don't need locks here XXX */ 01274 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 01275 if (iaxs[x]) { 01276 max = x + 1; 01277 } 01278 } 01279 01280 maxtrunkcall = max; 01281 if (option_debug && iaxdebug) 01282 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max); 01283 }
static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2200 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().
02201 { 02202 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 02203 struct ast_iax2_full_hdr *fh = f->data; 02204 /* Mark this as a retransmission */ 02205 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 02206 /* Update iseqno */ 02207 f->iseqno = iaxs[f->callno]->iseqno; 02208 fh->iseqno = f->iseqno; 02209 return 0; 02210 }
static int update_registry | ( | struct sockaddr_in * | sin, | |
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 6250 of file chan_iax2.c.
References iax2_peer::addr, ast_app_inboxcount(), ast_db_del(), ast_db_put(), ast_device_state_changed(), AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_verbose(), iax2_peer::cid_name, iax2_peer::cid_num, EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), globalflags, iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), iax_check_version(), IAX_COMMAND_REGACK, IAX_HASCALLERID, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_DATETIME, IAX_IE_FIRMWAREVER, IAX_IE_MSGCOUNT, IAX_IE_REFRESH, IAX_IE_USERNAME, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, iaxs, iaxsl, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax2_peer::mailbox, manager_event(), iax2_peer::name, option_verbose, peer_ref(), peer_unref(), realtime_update_peer(), register_peer_exten(), sched, send_command_final(), iax2_peer::sockfd, VERBOSE_PREFIX_3, and iax2_peer::zonetag.
Referenced by socket_process().
06251 { 06252 /* Called from IAX thread only, with proper iaxsl lock */ 06253 struct iax_ie_data ied; 06254 struct iax2_peer *p; 06255 int msgcount; 06256 char data[80]; 06257 int version; 06258 const char *peer_name; 06259 int res = -1; 06260 06261 memset(&ied, 0, sizeof(ied)); 06262 06263 peer_name = ast_strdupa(iaxs[callno]->peer); 06264 06265 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 06266 ast_mutex_unlock(&iaxsl[callno]); 06267 if (!(p = find_peer(peer_name, 1))) { 06268 ast_mutex_lock(&iaxsl[callno]); 06269 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 06270 return -1; 06271 } 06272 ast_mutex_lock(&iaxsl[callno]); 06273 if (!iaxs[callno]) 06274 goto return_unref; 06275 06276 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 06277 if (sin->sin_addr.s_addr) { 06278 time_t nowtime; 06279 time(&nowtime); 06280 realtime_update_peer(peer_name, sin, nowtime); 06281 } else { 06282 realtime_update_peer(peer_name, sin, 0); 06283 } 06284 } 06285 if (inaddrcmp(&p->addr, sin)) { 06286 if (iax2_regfunk) 06287 iax2_regfunk(p->name, 1); 06288 /* Stash the IP address from which they registered */ 06289 memcpy(&p->addr, sin, sizeof(p->addr)); 06290 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 06291 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 06292 ast_db_put("IAX/Registry", p->name, data); 06293 if (option_verbose > 2) 06294 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 06295 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 06296 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 06297 register_peer_exten(p, 1); 06298 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06299 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 06300 if (option_verbose > 2) 06301 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 06302 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 06303 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 06304 register_peer_exten(p, 0); 06305 ast_db_del("IAX/Registry", p->name); 06306 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06307 } 06308 /* Update the host */ 06309 /* Verify that the host is really there */ 06310 iax2_poke_peer(p, callno); 06311 } 06312 06313 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 06314 if (!iaxs[callno]) { 06315 res = -1; 06316 goto return_unref; 06317 } 06318 06319 /* Store socket fd */ 06320 p->sockfd = fd; 06321 /* Setup the expiry */ 06322 if (p->expire > -1) { 06323 if (!ast_sched_del(sched, p->expire)) { 06324 p->expire = -1; 06325 peer_unref(p); 06326 } 06327 } 06328 /* treat an unspecified refresh interval as the minimum */ 06329 if (!refresh) 06330 refresh = min_reg_expire; 06331 if (refresh > max_reg_expire) { 06332 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 06333 p->name, max_reg_expire, refresh); 06334 p->expiry = max_reg_expire; 06335 } else if (refresh < min_reg_expire) { 06336 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 06337 p->name, min_reg_expire, refresh); 06338 p->expiry = min_reg_expire; 06339 } else { 06340 p->expiry = refresh; 06341 } 06342 if (p->expiry && sin->sin_addr.s_addr) { 06343 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 06344 if (p->expire == -1) 06345 peer_unref(p); 06346 } 06347 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 06348 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 06349 if (sin->sin_addr.s_addr) { 06350 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 06351 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 06352 if (!ast_strlen_zero(p->mailbox)) { 06353 int new, old; 06354 ast_app_inboxcount(p->mailbox, &new, &old); 06355 if (new > 255) 06356 new = 255; 06357 if (old > 255) 06358 old = 255; 06359 msgcount = (old << 8) | new; 06360 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 06361 } 06362 if (ast_test_flag(p, IAX_HASCALLERID)) { 06363 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 06364 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 06365 } 06366 } 06367 version = iax_check_version(devtype); 06368 if (version) 06369 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 06370 06371 res = 0; 06372 06373 return_unref: 06374 peer_unref(p); 06375 06376 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 06377 }
static int user_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1140 of file chan_iax2.c.
References iax2_user::name.
Referenced by load_module().
01141 { 01142 struct iax2_user *user = obj, *user2 = arg; 01143 01144 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0; 01145 }
static int user_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9890 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
09891 { 09892 struct iax2_user *user = obj; 09893 09894 ast_set_flag(user, IAX_DELME); 09895 09896 return 0; 09897 }
static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 9654 of file chan_iax2.c.
References ast_free_ha(), ast_string_field_free_memory, ast_variables_destroy(), iax2_user::contexts, free_context(), iax2_user::ha, and iax2_user::vars.
Referenced by build_user().
09655 { 09656 struct iax2_user *user = obj; 09657 09658 ast_free_ha(user->ha); 09659 free_context(user->contexts); 09660 if(user->vars) { 09661 ast_variables_destroy(user->vars); 09662 user->vars = NULL; 09663 } 09664 ast_string_field_free_memory(user); 09665 }
static int user_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1130 of file chan_iax2.c.
References ast_str_hash(), and iax2_user::name.
Referenced by load_module().
01131 { 01132 const struct iax2_user *user = obj; 01133 01134 return ast_str_hash(user->name); 01135 }
Definition at line 1179 of file chan_iax2.c.
References ao2_ref().
01180 { 01181 ao2_ref(user, +1); 01182 return user; 01183 }
Definition at line 1185 of file chan_iax2.c.
References ao2_ref().
Referenced by authenticate_request(), authenticate_verify(), build_user(), check_access(), iax2_destroy_helper(), iax2_show_users(), prune_users(), and set_config().
01186 { 01187 ao2_ref(user, -1); 01188 return NULL; 01189 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 6572 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, f, iaxq, iaxs, iax_frame::list, ast_iax2_queue::queue, and send_packet().
Referenced by socket_process().
06573 { 06574 struct iax_frame *f; 06575 06576 AST_LIST_LOCK(&iaxq.queue); 06577 AST_LIST_TRAVERSE(&iaxq.queue, f, list) { 06578 /* Send a copy immediately */ 06579 if ((f->callno == callno) && iaxs[f->callno] && 06580 ((unsigned char ) (f->oseqno - last) < 128) && 06581 (f->retries >= 0)) { 06582 send_packet(f); 06583 } 06584 } 06585 AST_LIST_UNLOCK(&iaxq.queue); 06586 }
static int wait_for_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 3488 of file chan_iax2.c.
References chan_iax2_pvt::callno, DEADLOCK_AVOIDANCE, iaxs, iaxsl, and chan_iax2_pvt::peercallno.
Referenced by iax2_indicate(), and iax2_setoption().
03489 { 03490 unsigned short callno = pvt->callno; 03491 03492 if (!pvt->peercallno) { 03493 /* We don't know the remote side's call number, yet. :( */ 03494 int count = 10; 03495 while (count-- && pvt && !pvt->peercallno) { 03496 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 03497 pvt = iaxs[callno]; 03498 } 03499 if (!pvt->peercallno) { 03500 return -1; 03501 } 03502 } 03503 03504 return 0; 03505 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 11337 of file chan_iax2.c.
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 216 of file chan_iax2.c.
Referenced by __oh323_new(), ast_cdr_setaccount(), begin_dial(), build_device(), build_gateway(), check_user_full(), dahdi_new(), disa_exec(), features_call(), gtalk_new(), local_call(), mgcp_new(), sip_new(), skinny_new(), tds_log(), and wait_for_answer().
int adsi = 0 [static] |
int amaflags = 0 [static] |
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 11337 of file chan_iax2.c.
int authdebug = 1 [static] |
Definition at line 155 of file chan_iax2.c.
int autokill = 0 [static] |
Definition at line 156 of file chan_iax2.c.
struct ast_cli_entry cli_iax2[] [static] |
struct ast_cli_entry cli_iax2_jb_debug_deprecated [static] |
Initial value:
{ { "iax2", "jb", "debug", NULL }, iax2_do_jb_debug, NULL, NULL }
Definition at line 10980 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 10985 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 10995 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 10990 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 10975 of file chan_iax2.c.
char context[80] = "default" [static] |
Definition at line 142 of file chan_iax2.c.
char debug_jb_usage[] [static] |
Initial value:
"Usage: iax2 set debug jb\n" " Enables jitterbuffer debugging information\n"
Definition at line 10949 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 10941 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 10933 of file chan_iax2.c.
int defaultsockfd = -1 [static] |
Definition at line 173 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 221 of file chan_iax2.c.
struct iax2_dpcache * dpcache [static] |
Referenced by find_cache(), and iax2_show_cache().
ast_mutex_t dpcache_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Definition at line 688 of file chan_iax2.c.
Referenced by complete_dpreply(), find_cache(), iax2_canmatch(), iax2_exec(), iax2_exists(), iax2_matchmore(), iax2_show_cache(), and socket_process().
int global_rtautoclear = 120 [static] |
Definition at line 275 of file chan_iax2.c.
struct ast_flags globalflags = { 0 } [static] |
Definition at line 224 of file chan_iax2.c.
Referenced by __expire_registry(), __find_callno(), aji_create_client(), aji_load_config(), build_peer(), build_user(), find_or_create(), find_user(), find_user_realtime(), forward_message(), iax2_request(), iax2_trunk_queue(), load_config(), make_email_file(), notify_new_message(), populate_defaults(), send_trunk(), sendmail(), set_config(), set_config_destroy(), socket_process(), update_registry(), and vm_execmain().
int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static] |
Definition at line 202 of file chan_iax2.c.
int iax2_encryption = 0 [static] |
Definition at line 222 of file chan_iax2.c.
enum { ... } iax2_flags |
int(*) iax2_regfunk(const char *username, int onoff) = NULL |
Definition at line 175 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 10891 of file chan_iax2.c.
enum { ... } iax2_state |
struct ast_switch iax2_switch [static] |
struct ast_channel_tech iax2_tech [static] |
Definition at line 865 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 10957 of file chan_iax2.c.
struct ao2_container* iax_peercallno_pvts [static] |
Another container of iax2_pvt structures.
Active IAX2 pvt structs are also stored in this container, if they are a part of an active call where we know the remote side's call number. The reason for this is that incoming media frames do not contain our call number. So, instead of having to iterate the entire iaxs array, we use this container to look up calls where the remote side is using a given call number.
Definition at line 824 of file chan_iax2.c.
Referenced by __find_callno(), __unload_module(), load_module(), remove_by_peercallno(), and store_by_peercallno().
int iaxactivethreadcount = 0 [static] |
Definition at line 452 of file chan_iax2.c.
Referenced by __unload_module(), iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 157 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 204 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 160 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 162 of file chan_iax2.c.
int iaxdynamicthreadcount = 0 [static] |
Definition at line 450 of file chan_iax2.c.
Referenced by find_idle_thread(), and iax2_process_thread().
int iaxdynamicthreadnum = 0 [static] |
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 811 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __do_deliver(), __get_from_jb(), __unload_module(), ast_cli_netstats(), ast_iax2_new(), auth_fail(), auth_reject(), authenticate_reply(), authenticate_request(), auto_hangup(), cache_get_callno_locked(), calc_timestamp(), check_access(), complete_transfer(), decrypt_frame(), delete_users(), dp_lookup(), find_cache(), fix_peerts(), function_iaxpeer(), iax2_ack_registry(), iax2_bridge(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_poke_peer(), iax2_predestroy(), iax2_prov_app(), iax2_provision(), iax2_request(), iax2_setoption(), iax2_show_channels(), iax2_start_transfer(), iax2_vnak(), iax2_write(), iax_showframe(), load_module(), network_thread(), register_verify(), registry_authrequest(), registry_rerequest(), save_rr(), schedule_delivery(), send_command_final(), send_command_locked(), send_packet(), socket_process(), stop_stuff(), unwrap_timestamp(), update_packet(), update_registry(), vnak_retransmit(), and wait_for_peercallno().
ast_mutex_t iaxsl[ARRAY_LEN(iaxs)] [static] |
Definition at line 812 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __get_from_jb(), __iax2_poke_noanswer(), __unload_module(), ast_cli_netstats(), ast_iax2_new(), auth_reject(), authenticate_reply(), auto_hangup(), cache_get_callno_locked(), delete_users(), dp_lookup(), find_cache(), iax2_bridge(), iax2_call(), iax2_do_register(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_poke_peer(), iax2_provision(), iax2_request(), iax2_setoption(), iax2_show_channels(), iax2_write(), load_module(), lock_both(), network_thread(), peer_destructor(), register_verify(), registry_authrequest(), send_command_locked(), socket_process(), unlock_both(), update_registry(), and wait_for_peercallno().
int iaxthreadcount = DEFAULT_THREAD_COUNT [static] |
Definition at line 448 of file chan_iax2.c.
Referenced by iax2_show_threads(), set_config(), and start_network_thread().
int iaxtrunkdebug = 0 [static] |
Definition at line 206 of file chan_iax2.c.
struct io_context* io [static] |
Definition at line 199 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 150 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 144 of file chan_iax2.c.
int last_authmethod = 0 [static] |
Definition at line 158 of file chan_iax2.c.
Definition at line 813 of file chan_iax2.c.
int max_reg_expire [static] |
Definition at line 167 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 148 of file chan_iax2.c.
int maxauthreq = 3 [static] |
Definition at line 147 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 151 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 153 of file chan_iax2.c.
int maxnontrunkcall = 1 [static] |
Definition at line 831 of file chan_iax2.c.
int maxtrunkcall = TRUNK_CALL_START [static] |
Definition at line 830 of file chan_iax2.c.
int min_reg_expire [static] |
Definition at line 166 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 217 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 218 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 171 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 226 of file chan_iax2.c.
char no_debug_jb_usage[] [static] |
Initial value:
"Usage: iax2 set debug jb off\n" " Disables jitterbuffer debugging information\n"
Definition at line 10953 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 10945 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 10937 of file chan_iax2.c.
struct ast_netsock_list* outsock [static] |
used if sourceaddress specified and bindaddr == INADDR_ANY
Definition at line 172 of file chan_iax2.c.
Referenced by __unload_module(), load_module(), peer_set_srcaddr(), and set_config().
char* papp = "IAX2Provision" [static] |
Definition at line 8906 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 8908 of file chan_iax2.c.
struct ao2_container* peers [static] |
Definition at line 649 of file chan_iax2.c.
int ping_time = 21 [static] |
Definition at line 149 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 138 of file chan_iax2.c.
Referenced by ast_best_codec(), ast_rtp_codec_setpref(), build_peer(), build_user(), check_access(), create_addr(), gtalk_create_member(), gtalk_load_config(), new_iax(), set_config(), set_local_capabilities(), and set_peer_capabilities().
char prune_realtime_usage[] [static] |
Initial value:
"Usage: iax2 prune realtime [<peername>|all]\n" " Prunes object(s) from the cache\n"
Definition at line 10887 of file chan_iax2.c.
char* psyn = "Provision a calling IAXy with a given template" [static] |
Definition at line 8907 of file chan_iax2.c.
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 145 of file chan_iax2.c.
int resyncthreshold = 1000 [static] |
Definition at line 152 of file chan_iax2.c.
struct sched_context* sched [static] |
Definition at line 200 of file chan_iax2.c.
ast_cond_t sched_cond [static] |
Definition at line 229 of file chan_iax2.c.
ast_mutex_t sched_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Definition at line 228 of file chan_iax2.c.
Referenced by __unload_module(), iax2_sched_add(), iax2_transmit(), and sched_thread().
pthread_t schedthreadid = AST_PTHREADT_NULL [static] |
Definition at line 227 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 10879 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 10907 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 10925 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 10911 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 10883 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 10919 of file chan_iax2.c.
char show_prov_usage[] [static] |
Definition at line 10895 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 10929 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 10875 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 10915 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 10902 of file chan_iax2.c.
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 140 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 208 of file chan_iax2.c.
int timingfd = -1 [static] |
Definition at line 169 of file chan_iax2.c.
unsigned int tos = 0 [static] |
Definition at line 164 of file chan_iax2.c.
ast_mutex_t tpeerlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
struct iax2_trunk_peer * tpeers [static] |
Referenced by find_tpeer(), and timing_read().
int trunkfreq = 20 [static] |
Definition at line 154 of file chan_iax2.c.
struct ao2_container* users [static] |
Definition at line 652 of file chan_iax2.c.
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().