#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 & ~AST_FORMAT_AUDIO_UNDEFINED) |
#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 struct iax2_user * | find_user (const char *name) |
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 | remove_by_transfercallno (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 void | store_by_transfercallno (struct chan_iax2_pvt *pvt) |
static int | timing_read (int *id, int fd, short events, void *cbdata) |
static int | transfercallno_pvt_cmp_cb (void *obj, void *arg, int flags) |
static int | transfercallno_pvt_hash_cb (const void *obj, const int flags) |
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 struct ao2_container * | iax_transfercallno_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 & ~AST_FORMAT_AUDIO_UNDEFINED) |
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 1497 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 990 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 835 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 2266 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().
02267 { 02268 /* Attempt to transmit the frame to the remote peer... 02269 Called without iaxsl held. */ 02270 struct iax_frame *f = (struct iax_frame *)data; 02271 int freeme=0; 02272 int callno = f->callno; 02273 /* Make sure this call is still active */ 02274 if (callno) 02275 ast_mutex_lock(&iaxsl[callno]); 02276 if (callno && iaxs[callno]) { 02277 if ((f->retries < 0) /* Already ACK'd */ || 02278 (f->retries >= max_retries) /* Too many attempts */) { 02279 /* Record an error if we've transmitted too many times */ 02280 if (f->retries >= max_retries) { 02281 if (f->transfer) { 02282 /* Transfer timeout */ 02283 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 02284 } else if (f->final) { 02285 if (f->final) 02286 iax2_destroy(callno); 02287 } else { 02288 if (iaxs[callno]->owner) 02289 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); 02290 iaxs[callno]->error = ETIMEDOUT; 02291 if (iaxs[callno]->owner) { 02292 struct ast_frame fr = { 0, }; 02293 /* Hangup the fd */ 02294 fr.frametype = AST_FRAME_CONTROL; 02295 fr.subclass = AST_CONTROL_HANGUP; 02296 iax2_queue_frame(callno, &fr); // XXX 02297 /* Remember, owner could disappear */ 02298 if (iaxs[callno] && iaxs[callno]->owner) 02299 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 02300 } else { 02301 if (iaxs[callno]->reg) { 02302 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 02303 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 02304 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 02305 } 02306 iax2_destroy(callno); 02307 } 02308 } 02309 02310 } 02311 freeme++; 02312 } else { 02313 /* Update it if it needs it */ 02314 update_packet(f); 02315 /* Attempt transmission */ 02316 send_packet(f); 02317 f->retries++; 02318 /* Try again later after 10 times as long */ 02319 f->retrytime *= 10; 02320 if (f->retrytime > MAX_RETRY_TIME) 02321 f->retrytime = MAX_RETRY_TIME; 02322 /* Transfer messages max out at one second */ 02323 if (f->transfer && (f->retrytime > 1000)) 02324 f->retrytime = 1000; 02325 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 02326 } 02327 } else { 02328 /* Make sure it gets freed */ 02329 f->retries = -1; 02330 freeme++; 02331 } 02332 if (callno) 02333 ast_mutex_unlock(&iaxsl[callno]); 02334 /* Do not try again */ 02335 if (freeme) { 02336 /* Don't attempt delivery, just remove it from the queue */ 02337 AST_LIST_LOCK(&iaxq.queue); 02338 AST_LIST_REMOVE(&iaxq.queue, f, list); 02339 iaxq.count--; 02340 AST_LIST_UNLOCK(&iaxq.queue); 02341 f->retrans = -1; 02342 /* Free the IAX frame */ 02343 iax2_frame_free(f); 02344 } 02345 }
static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 6550 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().
06551 { 06552 /* Called from IAX thread only, without iaxs lock */ 06553 int callno = (int)(long)(nothing); 06554 struct iax_ie_data ied; 06555 ast_mutex_lock(&iaxsl[callno]); 06556 if (iaxs[callno]) { 06557 memset(&ied, 0, sizeof(ied)); 06558 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 06559 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 06560 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 06561 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 06562 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 06563 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 06564 } 06565 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 06566 } 06567 ast_mutex_unlock(&iaxsl[callno]); 06568 }
static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 3245 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().
03246 { 03247 int callno = PTR_TO_CALLNO(nothing); 03248 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 03249 ast_mutex_lock(&iaxsl[callno]); 03250 if (iaxs[callno]) { 03251 iaxs[callno]->initid = -1; 03252 iax2_queue_frame(callno, &f); 03253 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 03254 } 03255 ast_mutex_unlock(&iaxsl[callno]); 03256 }
static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 6599 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().
06600 { 06601 /* Called from IAX thread only, without iaxs lock */ 06602 int callno = (int)(long)(nothing); 06603 struct iax_ie_data ied; 06604 ast_mutex_lock(&iaxsl[callno]); 06605 if (iaxs[callno]) { 06606 memset(&ied, 0, sizeof(ied)); 06607 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 06608 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 06609 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 06610 } 06611 ast_mutex_unlock(&iaxsl[callno]); 06612 }
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 2133 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().
02134 { 02135 /* Just deliver the packet by using queueing. This is called by 02136 the IAX thread with the iaxsl lock held. */ 02137 struct iax_frame *fr = data; 02138 fr->retrans = -1; 02139 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 02140 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 02141 iax2_queue_frame(fr->callno, &fr->af); 02142 /* Free our iax frame */ 02143 iax2_frame_free(fr); 02144 /* And don't run again */ 02145 return 0; 02146 }
static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 6232 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().
06233 { 06234 struct iax2_peer *peer = (struct iax2_peer *) data; 06235 06236 if (!peer) 06237 return; 06238 06239 peer->expire = -1; 06240 06241 if (option_debug) 06242 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name); 06243 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 06244 realtime_update_peer(peer->name, &peer->addr, 0); 06245 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 06246 /* Reset the address */ 06247 memset(&peer->addr, 0, sizeof(peer->addr)); 06248 /* Reset expiry value */ 06249 peer->expiry = min_reg_expire; 06250 if (!ast_test_flag(peer, IAX_TEMPONLY)) 06251 ast_db_del("IAX/Registry", peer->name); 06252 register_peer_exten(peer, 0); 06253 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 06254 if (iax2_regfunk) 06255 iax2_regfunk(peer->name, 0); 06256 06257 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) 06258 unlink_peer(peer); 06259 06260 peer_unref(peer); 06261 }
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 1586 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_transfercallno_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(), chan_iax2_pvt::transfer, TRUNK_CALL_START, and update_max_nontrunk().
Referenced by find_callno(), and find_callno_locked().
01587 { 01588 int res = 0; 01589 int x; 01590 struct timeval now; 01591 char host[80]; 01592 01593 if (new <= NEW_ALLOW) { 01594 if (callno) { 01595 struct chan_iax2_pvt *pvt; 01596 struct chan_iax2_pvt tmp_pvt = { 01597 .callno = dcallno, 01598 .peercallno = callno, 01599 .transfercallno = callno, 01600 /* hack!! */ 01601 .frames_received = check_dcallno, 01602 }; 01603 01604 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 01605 /* this works for finding normal call numbers not involving transfering */ 01606 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 01607 if (return_locked) { 01608 ast_mutex_lock(&iaxsl[pvt->callno]); 01609 } 01610 res = pvt->callno; 01611 ao2_ref(pvt, -1); 01612 pvt = NULL; 01613 return res; 01614 } 01615 /* this searches for transfer call numbers that might not get caught otherwise */ 01616 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr)); 01617 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.addr)); 01618 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 01619 if (return_locked) { 01620 ast_mutex_lock(&iaxsl[pvt->callno]); 01621 } 01622 res = pvt->callno; 01623 ao2_ref(pvt, -1); 01624 pvt = NULL; 01625 return res; 01626 } 01627 } 01628 /* This will occur on the first response to a message that we initiated, 01629 * such as a PING. */ 01630 if (dcallno) { 01631 ast_mutex_lock(&iaxsl[dcallno]); 01632 } 01633 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) { 01634 iaxs[dcallno]->peercallno = callno; 01635 res = dcallno; 01636 store_by_peercallno(iaxs[dcallno]); 01637 if (!res || !return_locked) { 01638 ast_mutex_unlock(&iaxsl[dcallno]); 01639 } 01640 return res; 01641 } 01642 if (dcallno) { 01643 ast_mutex_unlock(&iaxsl[dcallno]); 01644 } 01645 #ifdef IAX_OLD_FIND 01646 /* If we get here, we SHOULD NOT find a call structure for this 01647 callno; if we do, it means that there is a call structure that 01648 has a peer callno but did NOT get entered into the hash table, 01649 which is bad. 01650 01651 If we find a call structure using this old, slow method, output a log 01652 message so we'll know about it. After a few months of leaving this in 01653 place, if we don't hear about people seeing these messages, we can 01654 remove this code for good. 01655 */ 01656 01657 for (x = 1; !res && x < maxnontrunkcall; x++) { 01658 ast_mutex_lock(&iaxsl[x]); 01659 if (iaxs[x]) { 01660 /* Look for an exact match */ 01661 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 01662 res = x; 01663 } 01664 } 01665 if (!res || !return_locked) 01666 ast_mutex_unlock(&iaxsl[x]); 01667 } 01668 01669 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 01670 ast_mutex_lock(&iaxsl[x]); 01671 if (iaxs[x]) { 01672 /* Look for an exact match */ 01673 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 01674 res = x; 01675 } 01676 } 01677 if (!res || !return_locked) 01678 ast_mutex_unlock(&iaxsl[x]); 01679 } 01680 01681 if (res) { 01682 ast_log(LOG_WARNING, "Old call search code found call number %d that was not in hash table!\n", res); 01683 } 01684 #endif 01685 } 01686 if (!res && (new >= NEW_ALLOW)) { 01687 int start, found = 0; 01688 01689 /* It may seem odd that we look through the peer list for a name for 01690 * this *incoming* call. Well, it is weird. However, users don't 01691 * have an IP address/port number that we can match against. So, 01692 * this is just checking for a peer that has that IP/port and 01693 * assuming that we have a user of the same name. This isn't always 01694 * correct, but it will be changed if needed after authentication. */ 01695 if (!iax2_getpeername(*sin, host, sizeof(host))) 01696 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 01697 01698 now = ast_tvnow(); 01699 start = 2 + (ast_random() % (TRUNK_CALL_START - 1)); 01700 for (x = start; 1; x++) { 01701 if (x == TRUNK_CALL_START) { 01702 x = 1; 01703 continue; 01704 } 01705 01706 /* Find first unused call number that hasn't been used in a while */ 01707 ast_mutex_lock(&iaxsl[x]); 01708 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01709 found = 1; 01710 break; 01711 } 01712 ast_mutex_unlock(&iaxsl[x]); 01713 01714 if (x == start - 1) { 01715 break; 01716 } 01717 } 01718 /* We've still got lock held if we found a spot */ 01719 if (x == start - 1 && !found) { 01720 ast_log(LOG_WARNING, "No more space\n"); 01721 return 0; 01722 } 01723 iaxs[x] = new_iax(sin, host); 01724 update_max_nontrunk(); 01725 if (iaxs[x]) { 01726 if (option_debug && iaxdebug) 01727 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x); 01728 iaxs[x]->sockfd = sockfd; 01729 iaxs[x]->addr.sin_port = sin->sin_port; 01730 iaxs[x]->addr.sin_family = sin->sin_family; 01731 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 01732 iaxs[x]->peercallno = callno; 01733 iaxs[x]->callno = x; 01734 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 01735 iaxs[x]->expiry = min_reg_expire; 01736 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01737 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01738 iaxs[x]->amaflags = amaflags; 01739 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 01740 01741 ast_string_field_set(iaxs[x], accountcode, accountcode); 01742 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 01743 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 01744 01745 if (iaxs[x]->peercallno) { 01746 store_by_peercallno(iaxs[x]); 01747 } 01748 } else { 01749 ast_log(LOG_WARNING, "Out of resources\n"); 01750 ast_mutex_unlock(&iaxsl[x]); 01751 return 0; 01752 } 01753 if (!return_locked) 01754 ast_mutex_unlock(&iaxsl[x]); 01755 res = x; 01756 } 01757 return res; 01758 }
static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 2687 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().
02688 { 02689 int callno = PTR_TO_CALLNO(p); 02690 struct chan_iax2_pvt *pvt = NULL; 02691 struct iax_frame *fr; 02692 jb_frame frame; 02693 int ret; 02694 long now; 02695 long next; 02696 struct timeval tv; 02697 02698 /* Make sure we have a valid private structure before going on */ 02699 ast_mutex_lock(&iaxsl[callno]); 02700 pvt = iaxs[callno]; 02701 if (!pvt) { 02702 /* No go! */ 02703 ast_mutex_unlock(&iaxsl[callno]); 02704 return; 02705 } 02706 02707 pvt->jbid = -1; 02708 02709 gettimeofday(&tv,NULL); 02710 /* round up a millisecond since ast_sched_runq does; */ 02711 /* prevents us from spinning while waiting for our now */ 02712 /* to catch up with runq's now */ 02713 tv.tv_usec += 1000; 02714 02715 now = ast_tvdiff_ms(tv, pvt->rxcore); 02716 02717 if(now >= (next = jb_next(pvt->jb))) { 02718 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat)); 02719 switch(ret) { 02720 case JB_OK: 02721 fr = frame.data; 02722 __do_deliver(fr); 02723 /* __do_deliver() can cause the call to disappear */ 02724 pvt = iaxs[callno]; 02725 break; 02726 case JB_INTERP: 02727 { 02728 struct ast_frame af = { 0, }; 02729 02730 /* create an interpolation frame */ 02731 af.frametype = AST_FRAME_VOICE; 02732 af.subclass = pvt->voiceformat; 02733 af.samples = frame.ms * 8; 02734 af.src = "IAX2 JB interpolation"; 02735 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 02736 af.offset = AST_FRIENDLY_OFFSET; 02737 02738 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 02739 * which we'd need to malloc, and then it would free it. That seems like a drag */ 02740 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) { 02741 iax2_queue_frame(callno, &af); 02742 /* iax2_queue_frame() could cause the call to disappear */ 02743 pvt = iaxs[callno]; 02744 } 02745 } 02746 break; 02747 case JB_DROP: 02748 iax2_frame_free(frame.data); 02749 break; 02750 case JB_NOFRAME: 02751 case JB_EMPTY: 02752 /* do nothing */ 02753 break; 02754 default: 02755 /* shouldn't happen */ 02756 break; 02757 } 02758 } 02759 if (pvt) 02760 update_jbsched(pvt); 02761 ast_mutex_unlock(&iaxsl[callno]); 02762 }
static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 5919 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
05920 { 05921 struct iax2_registry *reg = (struct iax2_registry *)data; 05922 reg->expire = -1; 05923 iax2_do_register(reg); 05924 }
static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 9043 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().
09044 { 09045 struct iax2_peer *peer = (struct iax2_peer *)data; 09046 int callno; 09047 09048 if (peer->lastms > -1) { 09049 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 09050 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 09051 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 09052 } 09053 if ((callno = peer->callno) > 0) { 09054 ast_mutex_lock(&iaxsl[callno]); 09055 iax2_destroy(callno); 09056 ast_mutex_unlock(&iaxsl[callno]); 09057 } 09058 peer->callno = 0; 09059 peer->lastms = -1; 09060 /* Try again quickly */ 09061 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 09062 if (peer->pokeexpire == -1) 09063 peer_unref(peer); 09064 }
static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 6662 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
06663 { 06664 struct iax2_peer *peer = (struct iax2_peer *)data; 06665 iax2_poke_peer(peer, 0); 06666 peer_unref(peer); 06667 }
static int __iax2_show_peers | ( | int | manager, | |
int | fd, | |||
struct mansession * | s, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4706 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().
04707 { 04708 regex_t regexbuf; 04709 int havepattern = 0; 04710 int total_peers = 0; 04711 int online_peers = 0; 04712 int offline_peers = 0; 04713 int unmonitored_peers = 0; 04714 struct ao2_iterator i; 04715 04716 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 04717 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 04718 04719 struct iax2_peer *peer = NULL; 04720 char name[256]; 04721 int registeredonly=0; 04722 char *term = manager ? "\r\n" : "\n"; 04723 04724 switch (argc) { 04725 case 6: 04726 if (!strcasecmp(argv[3], "registered")) 04727 registeredonly = 1; 04728 else 04729 return RESULT_SHOWUSAGE; 04730 if (!strcasecmp(argv[4], "like")) { 04731 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 04732 return RESULT_SHOWUSAGE; 04733 havepattern = 1; 04734 } else 04735 return RESULT_SHOWUSAGE; 04736 break; 04737 case 5: 04738 if (!strcasecmp(argv[3], "like")) { 04739 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04740 return RESULT_SHOWUSAGE; 04741 havepattern = 1; 04742 } else 04743 return RESULT_SHOWUSAGE; 04744 break; 04745 case 4: 04746 if (!strcasecmp(argv[3], "registered")) 04747 registeredonly = 1; 04748 else 04749 return RESULT_SHOWUSAGE; 04750 break; 04751 case 3: 04752 break; 04753 default: 04754 return RESULT_SHOWUSAGE; 04755 } 04756 04757 04758 if (s) 04759 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04760 else 04761 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04762 04763 i = ao2_iterator_init(peers, 0); 04764 for (peer = ao2_iterator_next(&i); peer; 04765 peer_unref(peer), peer = ao2_iterator_next(&i)) { 04766 char nm[20]; 04767 char status[20]; 04768 char srch[2000]; 04769 int retstatus; 04770 04771 if (registeredonly && !peer->addr.sin_addr.s_addr) 04772 continue; 04773 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 04774 continue; 04775 04776 if (!ast_strlen_zero(peer->username)) 04777 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 04778 else 04779 ast_copy_string(name, peer->name, sizeof(name)); 04780 04781 retstatus = peer_status(peer, status, sizeof(status)); 04782 if (retstatus > 0) 04783 online_peers++; 04784 else if (!retstatus) 04785 offline_peers++; 04786 else 04787 unmonitored_peers++; 04788 04789 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 04790 04791 snprintf(srch, sizeof(srch), FORMAT, name, 04792 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04793 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04794 nm, 04795 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04796 peer->encmethods ? "(E)" : " ", status, term); 04797 04798 if (s) 04799 astman_append(s, FORMAT, name, 04800 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)", 04801 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04802 nm, 04803 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04804 peer->encmethods ? "(E)" : " ", status, term); 04805 else 04806 ast_cli(fd, FORMAT, name, 04807 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04808 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04809 nm, 04810 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04811 peer->encmethods ? "(E)" : " ", status, term); 04812 total_peers++; 04813 } 04814 04815 if (s) 04816 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04817 else 04818 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04819 04820 if (havepattern) 04821 regfree(®exbuf); 04822 04823 return RESULT_SUCCESS; 04824 #undef FORMAT 04825 #undef FORMAT2 04826 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 11445 of file chan_iax2.c.
static int __schedule_action | ( | void(*)(const void *data) | func, | |
const void * | data, | |||
const char * | funcname | |||
) | [static] |
Definition at line 965 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.
00966 { 00967 struct iax2_thread *thread = NULL; 00968 static time_t lasterror; 00969 static time_t t; 00970 00971 thread = find_idle_thread(); 00972 00973 if (thread != NULL) { 00974 thread->schedfunc = func; 00975 thread->scheddata = data; 00976 thread->iostate = IAX_IOSTATE_SCHEDREADY; 00977 #ifdef DEBUG_SCHED_MULTITHREAD 00978 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 00979 #endif 00980 signal_condition(&thread->lock, &thread->cond); 00981 return 0; 00982 } 00983 time(&t); 00984 if (t != lasterror && option_debug) 00985 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n"); 00986 lasterror = t; 00987 00988 return -1; 00989 }
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 5207 of file chan_iax2.c.
References f, and iax2_send().
Referenced by send_command(), send_command_final(), send_command_immediate(), and send_command_transfer().
05209 { 05210 struct ast_frame f = { 0, }; 05211 05212 f.frametype = type; 05213 f.subclass = command; 05214 f.datalen = datalen; 05215 f.src = __FUNCTION__; 05216 f.data = (void *) data; 05217 05218 return iax2_send(i, &f, ts, seqno, now, transfer, final); 05219 }
static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1052 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().
01053 { 01054 int callno = (long) data; 01055 01056 ast_mutex_lock(&iaxsl[callno]); 01057 01058 if (iaxs[callno]) { 01059 if (iaxs[callno]->peercallno) { 01060 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01061 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01062 } else { 01063 /* I am the schedule, so I'm allowed to do this */ 01064 iaxs[callno]->lagid = -1; 01065 } 01066 } else { 01067 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); 01068 } 01069 01070 ast_mutex_unlock(&iaxsl[callno]); 01071 }
static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 1007 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().
01008 { 01009 int callno = (long) data; 01010 01011 ast_mutex_lock(&iaxsl[callno]); 01012 01013 if (iaxs[callno]) { 01014 if (iaxs[callno]->peercallno) { 01015 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01016 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01017 } else { 01018 /* I am the schedule, so I'm allowed to do this */ 01019 iaxs[callno]->pingid = -1; 01020 } 01021 } else if (option_debug > 0) { 01022 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); 01023 } 01024 01025 ast_mutex_unlock(&iaxsl[callno]); 01026 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 11180 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(), iax_transfercallno_pvts, 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.
11181 { 11182 struct iax2_thread *thread = NULL; 11183 int x; 11184 11185 /* Make sure threads do not hold shared resources when they are canceled */ 11186 11187 /* Grab the sched lock resource to keep it away from threads about to die */ 11188 /* Cancel the network thread, close the net socket */ 11189 if (netthreadid != AST_PTHREADT_NULL) { 11190 AST_LIST_LOCK(&iaxq.queue); 11191 ast_mutex_lock(&sched_lock); 11192 pthread_cancel(netthreadid); 11193 ast_cond_signal(&sched_cond); 11194 ast_mutex_unlock(&sched_lock); /* Release the schedule lock resource */ 11195 AST_LIST_UNLOCK(&iaxq.queue); 11196 pthread_join(netthreadid, NULL); 11197 } 11198 if (schedthreadid != AST_PTHREADT_NULL) { 11199 ast_mutex_lock(&sched_lock); 11200 pthread_cancel(schedthreadid); 11201 ast_cond_signal(&sched_cond); 11202 ast_mutex_unlock(&sched_lock); 11203 pthread_join(schedthreadid, NULL); 11204 } 11205 11206 /* Call for all threads to halt */ 11207 AST_LIST_LOCK(&idle_list); 11208 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) { 11209 AST_LIST_REMOVE_CURRENT(&idle_list, list); 11210 pthread_cancel(thread->threadid); 11211 } 11212 AST_LIST_TRAVERSE_SAFE_END 11213 AST_LIST_UNLOCK(&idle_list); 11214 11215 AST_LIST_LOCK(&active_list); 11216 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) { 11217 AST_LIST_REMOVE_CURRENT(&active_list, list); 11218 pthread_cancel(thread->threadid); 11219 } 11220 AST_LIST_TRAVERSE_SAFE_END 11221 AST_LIST_UNLOCK(&active_list); 11222 11223 AST_LIST_LOCK(&dynamic_list); 11224 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) { 11225 AST_LIST_REMOVE_CURRENT(&dynamic_list, list); 11226 pthread_cancel(thread->threadid); 11227 } 11228 AST_LIST_TRAVERSE_SAFE_END 11229 AST_LIST_UNLOCK(&dynamic_list); 11230 11231 AST_LIST_HEAD_DESTROY(&iaxq.queue); 11232 11233 /* Wait for threads to exit */ 11234 while(0 < iaxactivethreadcount) 11235 usleep(10000); 11236 11237 ast_netsock_release(netsock); 11238 ast_netsock_release(outsock); 11239 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 11240 if (iaxs[x]) { 11241 iax2_destroy(x); 11242 } 11243 } 11244 ast_manager_unregister( "IAXpeers" ); 11245 ast_manager_unregister( "IAXnetstats" ); 11246 ast_unregister_application(papp); 11247 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 11248 ast_unregister_switch(&iax2_switch); 11249 ast_channel_unregister(&iax2_tech); 11250 delete_users(); 11251 iax_provision_unload(); 11252 sched_context_destroy(sched); 11253 reload_firmware(1); 11254 11255 ast_mutex_destroy(&waresl.lock); 11256 11257 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 11258 ast_mutex_destroy(&iaxsl[x]); 11259 } 11260 11261 ao2_ref(peers, -1); 11262 ao2_ref(users, -1); 11263 ao2_ref(iax_peercallno_pvts, -1); 11264 ao2_ref(iax_transfercallno_pvts, -1); 11265 11266 return 0; 11267 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 11445 of file chan_iax2.c.
static int apply_context | ( | struct iax2_context * | con, | |
const char * | context | |||
) | [static] |
Definition at line 5260 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
05261 { 05262 while(con) { 05263 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 05264 return -1; 05265 con = con->next; 05266 } 05267 return 0; 05268 }
static int ast_cli_netstats | ( | struct mansession * | s, | |
int | fd, | |||
int | limit_fmt | |||
) | [static] |
Definition at line 5034 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().
05035 { 05036 int x; 05037 int numchans = 0; 05038 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 05039 ast_mutex_lock(&iaxsl[x]); 05040 if (iaxs[x]) { 05041 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 05042 char *fmt; 05043 jb_info jbinfo; 05044 05045 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 05046 jb_getinfo(iaxs[x]->jb, &jbinfo); 05047 localjitter = jbinfo.jitter; 05048 localdelay = jbinfo.current - jbinfo.min; 05049 locallost = jbinfo.frames_lost; 05050 locallosspct = jbinfo.losspct/1000; 05051 localdropped = jbinfo.frames_dropped; 05052 localooo = jbinfo.frames_ooo; 05053 } else { 05054 localjitter = -1; 05055 localdelay = 0; 05056 locallost = -1; 05057 locallosspct = -1; 05058 localdropped = 0; 05059 localooo = -1; 05060 } 05061 if (limit_fmt) 05062 fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n"; 05063 else 05064 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"; 05065 if (s) 05066 05067 astman_append(s, fmt, 05068 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 05069 iaxs[x]->pingtime, 05070 localjitter, 05071 localdelay, 05072 locallost, 05073 locallosspct, 05074 localdropped, 05075 localooo, 05076 iaxs[x]->frames_received/1000, 05077 iaxs[x]->remote_rr.jitter, 05078 iaxs[x]->remote_rr.delay, 05079 iaxs[x]->remote_rr.losscnt, 05080 iaxs[x]->remote_rr.losspct, 05081 iaxs[x]->remote_rr.dropped, 05082 iaxs[x]->remote_rr.ooo, 05083 iaxs[x]->remote_rr.packets/1000); 05084 else 05085 ast_cli(fd, fmt, 05086 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 05087 iaxs[x]->pingtime, 05088 localjitter, 05089 localdelay, 05090 locallost, 05091 locallosspct, 05092 localdropped, 05093 localooo, 05094 iaxs[x]->frames_received/1000, 05095 iaxs[x]->remote_rr.jitter, 05096 iaxs[x]->remote_rr.delay, 05097 iaxs[x]->remote_rr.losscnt, 05098 iaxs[x]->remote_rr.losspct, 05099 iaxs[x]->remote_rr.dropped, 05100 iaxs[x]->remote_rr.ooo, 05101 iaxs[x]->remote_rr.packets/1000 05102 ); 05103 numchans++; 05104 } 05105 ast_mutex_unlock(&iaxsl[x]); 05106 } 05107 return numchans; 05108 }
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 3910 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().
03911 { 03912 struct ast_channel *tmp; 03913 struct chan_iax2_pvt *i; 03914 struct ast_variable *v = NULL; 03915 03916 if (!(i = iaxs[callno])) { 03917 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 03918 return NULL; 03919 } 03920 03921 /* Don't hold call lock */ 03922 ast_mutex_unlock(&iaxsl[callno]); 03923 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); 03924 ast_mutex_lock(&iaxsl[callno]); 03925 if (i != iaxs[callno]) { 03926 if (tmp) { 03927 /* unlock and relock iaxsl[callno] to preserve locking order */ 03928 ast_mutex_unlock(&iaxsl[callno]); 03929 ast_channel_free(tmp); 03930 ast_mutex_lock(&iaxsl[callno]); 03931 } 03932 return NULL; 03933 } 03934 03935 if (!tmp) 03936 return NULL; 03937 tmp->tech = &iax2_tech; 03938 /* We can support any format by default, until we get restricted */ 03939 tmp->nativeformats = capability; 03940 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability); 03941 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability); 03942 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 03943 03944 /* Don't use ast_set_callerid() here because it will 03945 * generate a NewCallerID event before the NewChannel event */ 03946 if (!ast_strlen_zero(i->ani)) 03947 tmp->cid.cid_ani = ast_strdup(i->ani); 03948 else 03949 tmp->cid.cid_ani = ast_strdup(i->cid_num); 03950 tmp->cid.cid_dnid = ast_strdup(i->dnid); 03951 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 03952 tmp->cid.cid_pres = i->calling_pres; 03953 tmp->cid.cid_ton = i->calling_ton; 03954 tmp->cid.cid_tns = i->calling_tns; 03955 if (!ast_strlen_zero(i->language)) 03956 ast_string_field_set(tmp, language, i->language); 03957 if (!ast_strlen_zero(i->accountcode)) 03958 ast_string_field_set(tmp, accountcode, i->accountcode); 03959 if (i->amaflags) 03960 tmp->amaflags = i->amaflags; 03961 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 03962 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 03963 if (i->adsi) 03964 tmp->adsicpe = i->peeradsicpe; 03965 else 03966 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 03967 i->owner = tmp; 03968 i->capability = capability; 03969 03970 for (v = i->vars ; v ; v = v->next) 03971 pbx_builtin_setvar_helper(tmp, v->name, v->value); 03972 03973 if (state != AST_STATE_DOWN) { 03974 if (ast_pbx_start(tmp)) { 03975 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 03976 ast_hangup(tmp); 03977 i->owner = NULL; 03978 return NULL; 03979 } 03980 } 03981 03982 ast_module_ref(ast_module_info->self); 03983 03984 return tmp; 03985 }
static int attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 2347 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and network_thread().
02348 { 02349 #ifdef SCHED_MULTITHREADED 02350 if (schedule_action(__attempt_transmit, data)) 02351 #endif 02352 __attempt_transmit(data); 02353 return 0; 02354 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 6584 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().
06585 { 06586 /* Schedule sending the authentication failure in one second, to prevent 06587 guessing */ 06588 if (iaxs[callno]) { 06589 iaxs[callno]->authfail = failcode; 06590 if (delayreject) { 06591 AST_SCHED_DEL(sched, iaxs[callno]->authid); 06592 iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno); 06593 } else 06594 auth_reject((void *)(long)callno); 06595 } 06596 return 0; 06597 }
static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 6570 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().
06571 { 06572 int callno = (int)(long)(data); 06573 ast_mutex_lock(&iaxsl[callno]); 06574 if (iaxs[callno]) 06575 iaxs[callno]->authid = -1; 06576 ast_mutex_unlock(&iaxsl[callno]); 06577 #ifdef SCHED_MULTITHREADED 06578 if (schedule_action(__auth_reject, data)) 06579 #endif 06580 __auth_reject(data); 06581 return 0; 06582 }
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 5788 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().
05789 { 05790 int res = -1; 05791 int x; 05792 if (!ast_strlen_zero(keyn)) { 05793 if (!(authmethods & IAX_AUTH_RSA)) { 05794 if (ast_strlen_zero(secret)) 05795 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)); 05796 } else if (ast_strlen_zero(challenge)) { 05797 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 05798 } else { 05799 char sig[256]; 05800 struct ast_key *key; 05801 key = ast_key_get(keyn, AST_KEY_PRIVATE); 05802 if (!key) { 05803 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 05804 } else { 05805 if (ast_sign(key, (char*)challenge, sig)) { 05806 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 05807 res = -1; 05808 } else { 05809 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 05810 res = 0; 05811 } 05812 } 05813 } 05814 } 05815 /* Fall back */ 05816 if (res && !ast_strlen_zero(secret)) { 05817 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 05818 struct MD5Context md5; 05819 unsigned char digest[16]; 05820 char digres[128]; 05821 MD5Init(&md5); 05822 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 05823 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 05824 MD5Final(digest, &md5); 05825 /* If they support md5, authenticate with it. */ 05826 for (x=0;x<16;x++) 05827 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 05828 if (ecx && dcx) 05829 build_enc_keys(digest, ecx, dcx); 05830 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 05831 res = 0; 05832 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 05833 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 05834 res = 0; 05835 } else 05836 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 05837 } 05838 return res; 05839 }
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 5845 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().
05846 { 05847 struct iax2_peer *peer = NULL; 05848 /* Start pessimistic */ 05849 int res = -1; 05850 int authmethods = 0; 05851 struct iax_ie_data ied; 05852 uint16_t callno = p->callno; 05853 05854 memset(&ied, 0, sizeof(ied)); 05855 05856 if (ies->username) 05857 ast_string_field_set(p, username, ies->username); 05858 if (ies->challenge) 05859 ast_string_field_set(p, challenge, ies->challenge); 05860 if (ies->authmethods) 05861 authmethods = ies->authmethods; 05862 if (authmethods & IAX_AUTH_MD5) 05863 merge_encryption(p, ies->encmethods); 05864 else 05865 p->encmethods = 0; 05866 05867 /* Check for override RSA authentication first */ 05868 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 05869 /* Normal password authentication */ 05870 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05871 } else { 05872 struct ao2_iterator i = ao2_iterator_init(peers, 0); 05873 while ((peer = ao2_iterator_next(&i))) { 05874 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 05875 /* No peer specified at our end, or this is the peer */ 05876 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 05877 /* No username specified in peer rule, or this is the right username */ 05878 && (!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))) 05879 /* No specified host, or this is our host */ 05880 ) { 05881 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05882 if (!res) { 05883 peer_unref(peer); 05884 break; 05885 } 05886 } 05887 peer_unref(peer); 05888 } 05889 if (!peer) { 05890 /* We checked our list and didn't find one. It's unlikely, but possible, 05891 that we're trying to authenticate *to* a realtime peer */ 05892 const char *peer_name = ast_strdupa(p->peer); 05893 ast_mutex_unlock(&iaxsl[callno]); 05894 if ((peer = realtime_peer(peer_name, NULL))) { 05895 ast_mutex_lock(&iaxsl[callno]); 05896 if (!(p = iaxs[callno])) { 05897 peer_unref(peer); 05898 return -1; 05899 } 05900 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05901 peer_unref(peer); 05902 } 05903 if (!peer) { 05904 ast_mutex_lock(&iaxsl[callno]); 05905 if (!(p = iaxs[callno])) 05906 return -1; 05907 } 05908 } 05909 } 05910 if (ies->encmethods) 05911 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 05912 if (!res) 05913 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 05914 return res; 05915 }
static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 5517 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().
05518 { 05519 struct iax_ie_data ied; 05520 int res = -1, authreq_restrict = 0; 05521 char challenge[10]; 05522 struct chan_iax2_pvt *p = iaxs[call_num]; 05523 05524 memset(&ied, 0, sizeof(ied)); 05525 05526 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 05527 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05528 struct iax2_user *user, tmp_user = { 05529 .name = p->username, 05530 }; 05531 05532 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05533 if (user) { 05534 if (user->curauthreq == user->maxauthreq) 05535 authreq_restrict = 1; 05536 else 05537 user->curauthreq++; 05538 user = user_unref(user); 05539 } 05540 } 05541 05542 /* If the AUTHREQ limit test failed, send back an error */ 05543 if (authreq_restrict) { 05544 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 05545 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 05546 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 05547 return 0; 05548 } 05549 05550 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 05551 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 05552 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 05553 ast_string_field_set(p, challenge, challenge); 05554 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 05555 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 05556 } 05557 if (p->encmethods) 05558 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 05559 05560 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 05561 05562 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 05563 05564 if (p->encmethods) 05565 ast_set_flag(p, IAX_ENCRYPTED); 05566 05567 return res; 05568 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5570 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().
05571 { 05572 char requeststr[256]; 05573 char md5secret[256] = ""; 05574 char secret[256] = ""; 05575 char rsasecret[256] = ""; 05576 int res = -1; 05577 int x; 05578 struct iax2_user *user, tmp_user = { 05579 .name = p->username, 05580 }; 05581 05582 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05583 if (user) { 05584 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05585 ast_atomic_fetchadd_int(&user->curauthreq, -1); 05586 ast_clear_flag(p, IAX_MAXAUTHREQ); 05587 } 05588 ast_string_field_set(p, host, user->name); 05589 user = user_unref(user); 05590 } 05591 05592 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 05593 return res; 05594 if (ies->password) 05595 ast_copy_string(secret, ies->password, sizeof(secret)); 05596 if (ies->md5_result) 05597 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05598 if (ies->rsa_result) 05599 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05600 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 05601 struct ast_key *key; 05602 char *keyn; 05603 char tmpkey[256]; 05604 char *stringp=NULL; 05605 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 05606 stringp=tmpkey; 05607 keyn = strsep(&stringp, ":"); 05608 while(keyn) { 05609 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05610 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 05611 res = 0; 05612 break; 05613 } else if (!key) 05614 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 05615 keyn = strsep(&stringp, ":"); 05616 } 05617 } else if (p->authmethods & IAX_AUTH_MD5) { 05618 struct MD5Context md5; 05619 unsigned char digest[16]; 05620 char *tmppw, *stringp; 05621 05622 tmppw = ast_strdupa(p->secret); 05623 stringp = tmppw; 05624 while((tmppw = strsep(&stringp, ";"))) { 05625 MD5Init(&md5); 05626 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 05627 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05628 MD5Final(digest, &md5); 05629 /* If they support md5, authenticate with it. */ 05630 for (x=0;x<16;x++) 05631 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05632 if (!strcasecmp(requeststr, md5secret)) { 05633 res = 0; 05634 break; 05635 } 05636 } 05637 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 05638 if (!strcmp(secret, p->secret)) 05639 res = 0; 05640 } 05641 return res; 05642 }
static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 3258 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), and sip_call().
03259 { 03260 #ifdef SCHED_MULTITHREADED 03261 if (schedule_action(__auto_congest, data)) 03262 #endif 03263 __auto_congest(data); 03264 return 0; 03265 }
static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 6614 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().
06615 { 06616 int callno = (int)(long)(data); 06617 ast_mutex_lock(&iaxsl[callno]); 06618 if (iaxs[callno]) { 06619 iaxs[callno]->autoid = -1; 06620 } 06621 ast_mutex_unlock(&iaxsl[callno]); 06622 #ifdef SCHED_MULTITHREADED 06623 if (schedule_action(__auto_hangup, data)) 06624 #endif 06625 __auto_hangup(data); 06626 return 0; 06627 }
static struct iax2_context* build_context | ( | char * | context | ) | [static] |
Definition at line 9371 of file chan_iax2.c.
References ast_calloc, and ast_copy_string().
Referenced by build_user().
09372 { 09373 struct iax2_context *con; 09374 09375 if ((con = ast_calloc(1, sizeof(*con)))) 09376 ast_copy_string(con->context, context, sizeof(con->context)); 09377 09378 return con; 09379 }
static void build_enc_keys | ( | const unsigned char * | digest, | |
aes_encrypt_ctx * | ecx, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 4292 of file chan_iax2.c.
References aes_decrypt_key128(), and aes_encrypt_key128().
Referenced by authenticate(), and decrypt_frame().
04293 { 04294 aes_encrypt_key128(digest, ecx); 04295 aes_decrypt_key128(digest, dcx); 04296 }
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 9518 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.
09519 { 09520 struct iax2_peer *peer = NULL; 09521 struct ast_ha *oldha = NULL; 09522 int maskfound=0; 09523 int found=0; 09524 int firstpass=1; 09525 struct iax2_peer tmp_peer = { 09526 .name = name, 09527 }; 09528 09529 if (!temponly) { 09530 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 09531 if (peer && !ast_test_flag(peer, IAX_DELME)) 09532 firstpass = 0; 09533 } 09534 09535 if (peer) { 09536 found++; 09537 if (firstpass) { 09538 oldha = peer->ha; 09539 peer->ha = NULL; 09540 } 09541 unlink_peer(peer); 09542 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 09543 peer->expire = -1; 09544 peer->pokeexpire = -1; 09545 peer->sockfd = defaultsockfd; 09546 if (ast_string_field_init(peer, 32)) 09547 peer = peer_unref(peer); 09548 } 09549 09550 if (peer) { 09551 if (firstpass) { 09552 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09553 peer->encmethods = iax2_encryption; 09554 peer->adsi = adsi; 09555 ast_string_field_set(peer,secret,""); 09556 if (!found) { 09557 ast_string_field_set(peer, name, name); 09558 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09559 peer->expiry = min_reg_expire; 09560 } 09561 peer->prefs = prefs; 09562 peer->capability = iax2_capability; 09563 peer->smoothing = 0; 09564 peer->pokefreqok = DEFAULT_FREQ_OK; 09565 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 09566 ast_string_field_set(peer,context,""); 09567 ast_string_field_set(peer,peercontext,""); 09568 ast_clear_flag(peer, IAX_HASCALLERID); 09569 ast_string_field_set(peer, cid_name, ""); 09570 ast_string_field_set(peer, cid_num, ""); 09571 } 09572 09573 if (!v) { 09574 v = alt; 09575 alt = NULL; 09576 } 09577 while(v) { 09578 if (!strcasecmp(v->name, "secret")) { 09579 ast_string_field_set(peer, secret, v->value); 09580 } else if (!strcasecmp(v->name, "mailbox")) { 09581 ast_string_field_set(peer, mailbox, v->value); 09582 } else if (!strcasecmp(v->name, "hasvoicemail")) { 09583 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 09584 ast_string_field_set(peer, mailbox, name); 09585 } 09586 } else if (!strcasecmp(v->name, "mohinterpret")) { 09587 ast_string_field_set(peer, mohinterpret, v->value); 09588 } else if (!strcasecmp(v->name, "mohsuggest")) { 09589 ast_string_field_set(peer, mohsuggest, v->value); 09590 } else if (!strcasecmp(v->name, "dbsecret")) { 09591 ast_string_field_set(peer, dbsecret, v->value); 09592 } else if (!strcasecmp(v->name, "trunk")) { 09593 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 09594 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) { 09595 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without timing\n", peer->name); 09596 ast_clear_flag(peer, IAX_TRUNK); 09597 } 09598 } else if (!strcasecmp(v->name, "auth")) { 09599 peer->authmethods = get_auth_methods(v->value); 09600 } else if (!strcasecmp(v->name, "encryption")) { 09601 peer->encmethods = get_encrypt_methods(v->value); 09602 } else if (!strcasecmp(v->name, "notransfer")) { 09603 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09604 ast_clear_flag(peer, IAX_TRANSFERMEDIA); 09605 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 09606 } else if (!strcasecmp(v->name, "transfer")) { 09607 if (!strcasecmp(v->value, "mediaonly")) { 09608 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09609 } else if (ast_true(v->value)) { 09610 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09611 } else 09612 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09613 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09614 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 09615 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09616 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 09617 } else if (!strcasecmp(v->name, "host")) { 09618 if (!strcasecmp(v->value, "dynamic")) { 09619 /* They'll register with us */ 09620 ast_set_flag(peer, IAX_DYNAMIC); 09621 if (!found) { 09622 /* Initialize stuff iff we're not found, otherwise 09623 we keep going with what we had */ 09624 memset(&peer->addr.sin_addr, 0, 4); 09625 if (peer->addr.sin_port) { 09626 /* If we've already got a port, make it the default rather than absolute */ 09627 peer->defaddr.sin_port = peer->addr.sin_port; 09628 peer->addr.sin_port = 0; 09629 } 09630 } 09631 } else { 09632 /* Non-dynamic. Make sure we become that way if we're not */ 09633 AST_SCHED_DEL(sched, peer->expire); 09634 ast_clear_flag(peer, IAX_DYNAMIC); 09635 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) 09636 return peer_unref(peer); 09637 if (!peer->addr.sin_port) 09638 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09639 } 09640 if (!maskfound) 09641 inet_aton("255.255.255.255", &peer->mask); 09642 } else if (!strcasecmp(v->name, "defaultip")) { 09643 if (ast_get_ip(&peer->defaddr, v->value)) 09644 return peer_unref(peer); 09645 } else if (!strcasecmp(v->name, "sourceaddress")) { 09646 peer_set_srcaddr(peer, v->value); 09647 } else if (!strcasecmp(v->name, "permit") || 09648 !strcasecmp(v->name, "deny")) { 09649 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 09650 } else if (!strcasecmp(v->name, "mask")) { 09651 maskfound++; 09652 inet_aton(v->value, &peer->mask); 09653 } else if (!strcasecmp(v->name, "context")) { 09654 ast_string_field_set(peer, context, v->value); 09655 } else if (!strcasecmp(v->name, "regexten")) { 09656 ast_string_field_set(peer, regexten, v->value); 09657 } else if (!strcasecmp(v->name, "peercontext")) { 09658 ast_string_field_set(peer, peercontext, v->value); 09659 } else if (!strcasecmp(v->name, "port")) { 09660 if (ast_test_flag(peer, IAX_DYNAMIC)) 09661 peer->defaddr.sin_port = htons(atoi(v->value)); 09662 else 09663 peer->addr.sin_port = htons(atoi(v->value)); 09664 } else if (!strcasecmp(v->name, "username")) { 09665 ast_string_field_set(peer, username, v->value); 09666 } else if (!strcasecmp(v->name, "allow")) { 09667 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 09668 } else if (!strcasecmp(v->name, "disallow")) { 09669 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 09670 } else if (!strcasecmp(v->name, "callerid")) { 09671 if (!ast_strlen_zero(v->value)) { 09672 char name2[80]; 09673 char num2[80]; 09674 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 09675 ast_string_field_set(peer, cid_name, name2); 09676 ast_string_field_set(peer, cid_num, num2); 09677 } else { 09678 ast_string_field_set(peer, cid_name, ""); 09679 ast_string_field_set(peer, cid_num, ""); 09680 } 09681 ast_set_flag(peer, IAX_HASCALLERID); 09682 } else if (!strcasecmp(v->name, "fullname")) { 09683 ast_string_field_set(peer, cid_name, S_OR(v->value, "")); 09684 ast_set_flag(peer, IAX_HASCALLERID); 09685 } else if (!strcasecmp(v->name, "cid_number")) { 09686 ast_string_field_set(peer, cid_num, S_OR(v->value, "")); 09687 ast_set_flag(peer, IAX_HASCALLERID); 09688 } else if (!strcasecmp(v->name, "sendani")) { 09689 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 09690 } else if (!strcasecmp(v->name, "inkeys")) { 09691 ast_string_field_set(peer, inkeys, v->value); 09692 } else if (!strcasecmp(v->name, "outkey")) { 09693 ast_string_field_set(peer, outkey, v->value); 09694 } else if (!strcasecmp(v->name, "qualify")) { 09695 if (!strcasecmp(v->value, "no")) { 09696 peer->maxms = 0; 09697 } else if (!strcasecmp(v->value, "yes")) { 09698 peer->maxms = DEFAULT_MAXMS; 09699 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 09700 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); 09701 peer->maxms = 0; 09702 } 09703 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 09704 peer->smoothing = ast_true(v->value); 09705 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 09706 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) { 09707 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); 09708 } 09709 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 09710 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) { 09711 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); 09712 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 09713 } else if (!strcasecmp(v->name, "timezone")) { 09714 ast_string_field_set(peer, zonetag, v->value); 09715 } else if (!strcasecmp(v->name, "adsi")) { 09716 peer->adsi = ast_true(v->value); 09717 }/* else if (strcasecmp(v->name,"type")) */ 09718 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09719 v = v->next; 09720 if (!v) { 09721 v = alt; 09722 alt = NULL; 09723 } 09724 } 09725 if (!peer->authmethods) 09726 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09727 ast_clear_flag(peer, IAX_DELME); 09728 /* Make sure these are IPv4 addresses */ 09729 peer->addr.sin_family = AF_INET; 09730 } 09731 if (oldha) 09732 ast_free_ha(oldha); 09733 return peer; 09734 }
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 9750 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.
09751 { 09752 struct iax2_user *user = NULL; 09753 struct iax2_context *con, *conl = NULL; 09754 struct ast_ha *oldha = NULL; 09755 struct iax2_context *oldcon = NULL; 09756 int format; 09757 int firstpass=1; 09758 int oldcurauthreq = 0; 09759 char *varname = NULL, *varval = NULL; 09760 struct ast_variable *tmpvar = NULL; 09761 struct iax2_user tmp_user = { 09762 .name = name, 09763 }; 09764 09765 if (!temponly) { 09766 user = ao2_find(users, &tmp_user, OBJ_POINTER); 09767 if (user && !ast_test_flag(user, IAX_DELME)) 09768 firstpass = 0; 09769 } 09770 09771 if (user) { 09772 if (firstpass) { 09773 oldcurauthreq = user->curauthreq; 09774 oldha = user->ha; 09775 oldcon = user->contexts; 09776 user->ha = NULL; 09777 user->contexts = NULL; 09778 } 09779 /* Already in the list, remove it and it will be added back (or FREE'd) */ 09780 ao2_unlink(users, user); 09781 } else { 09782 user = ao2_alloc(sizeof(*user), user_destructor); 09783 } 09784 09785 if (user) { 09786 if (firstpass) { 09787 ast_string_field_free_memory(user); 09788 memset(user, 0, sizeof(struct iax2_user)); 09789 if (ast_string_field_init(user, 32)) { 09790 user = user_unref(user); 09791 goto cleanup; 09792 } 09793 user->maxauthreq = maxauthreq; 09794 user->curauthreq = oldcurauthreq; 09795 user->prefs = prefs; 09796 user->capability = iax2_capability; 09797 user->encmethods = iax2_encryption; 09798 user->adsi = adsi; 09799 ast_string_field_set(user, name, name); 09800 ast_string_field_set(user, language, language); 09801 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 09802 ast_clear_flag(user, IAX_HASCALLERID); 09803 ast_string_field_set(user, cid_name, ""); 09804 ast_string_field_set(user, cid_num, ""); 09805 } 09806 if (!v) { 09807 v = alt; 09808 alt = NULL; 09809 } 09810 while(v) { 09811 if (!strcasecmp(v->name, "context")) { 09812 con = build_context(v->value); 09813 if (con) { 09814 if (conl) 09815 conl->next = con; 09816 else 09817 user->contexts = con; 09818 conl = con; 09819 } 09820 } else if (!strcasecmp(v->name, "permit") || 09821 !strcasecmp(v->name, "deny")) { 09822 user->ha = ast_append_ha(v->name, v->value, user->ha); 09823 } else if (!strcasecmp(v->name, "setvar")) { 09824 varname = ast_strdupa(v->value); 09825 if (varname && (varval = strchr(varname,'='))) { 09826 *varval = '\0'; 09827 varval++; 09828 if((tmpvar = ast_variable_new(varname, varval))) { 09829 tmpvar->next = user->vars; 09830 user->vars = tmpvar; 09831 } 09832 } 09833 } else if (!strcasecmp(v->name, "allow")) { 09834 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 09835 } else if (!strcasecmp(v->name, "disallow")) { 09836 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 09837 } else if (!strcasecmp(v->name, "trunk")) { 09838 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 09839 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) { 09840 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without timing\n", user->name); 09841 ast_clear_flag(user, IAX_TRUNK); 09842 } 09843 } else if (!strcasecmp(v->name, "auth")) { 09844 user->authmethods = get_auth_methods(v->value); 09845 } else if (!strcasecmp(v->name, "encryption")) { 09846 user->encmethods = get_encrypt_methods(v->value); 09847 } else if (!strcasecmp(v->name, "notransfer")) { 09848 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09849 ast_clear_flag(user, IAX_TRANSFERMEDIA); 09850 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 09851 } else if (!strcasecmp(v->name, "transfer")) { 09852 if (!strcasecmp(v->value, "mediaonly")) { 09853 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09854 } else if (ast_true(v->value)) { 09855 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09856 } else 09857 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09858 } else if (!strcasecmp(v->name, "codecpriority")) { 09859 if(!strcasecmp(v->value, "caller")) 09860 ast_set_flag(user, IAX_CODEC_USER_FIRST); 09861 else if(!strcasecmp(v->value, "disabled")) 09862 ast_set_flag(user, IAX_CODEC_NOPREFS); 09863 else if(!strcasecmp(v->value, "reqonly")) { 09864 ast_set_flag(user, IAX_CODEC_NOCAP); 09865 ast_set_flag(user, IAX_CODEC_NOPREFS); 09866 } 09867 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09868 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 09869 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09870 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 09871 } else if (!strcasecmp(v->name, "dbsecret")) { 09872 ast_string_field_set(user, dbsecret, v->value); 09873 } else if (!strcasecmp(v->name, "secret")) { 09874 if (!ast_strlen_zero(user->secret)) { 09875 char *old = ast_strdupa(user->secret); 09876 09877 ast_string_field_build(user, secret, "%s;%s", old, v->value); 09878 } else 09879 ast_string_field_set(user, secret, v->value); 09880 } else if (!strcasecmp(v->name, "callerid")) { 09881 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 09882 char name2[80]; 09883 char num2[80]; 09884 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 09885 ast_string_field_set(user, cid_name, name2); 09886 ast_string_field_set(user, cid_num, num2); 09887 ast_set_flag(user, IAX_HASCALLERID); 09888 } else { 09889 ast_clear_flag(user, IAX_HASCALLERID); 09890 ast_string_field_set(user, cid_name, ""); 09891 ast_string_field_set(user, cid_num, ""); 09892 } 09893 } else if (!strcasecmp(v->name, "fullname")) { 09894 if (!ast_strlen_zero(v->value)) { 09895 ast_string_field_set(user, cid_name, v->value); 09896 ast_set_flag(user, IAX_HASCALLERID); 09897 } else { 09898 ast_string_field_set(user, cid_name, ""); 09899 if (ast_strlen_zero(user->cid_num)) 09900 ast_clear_flag(user, IAX_HASCALLERID); 09901 } 09902 } else if (!strcasecmp(v->name, "cid_number")) { 09903 if (!ast_strlen_zero(v->value)) { 09904 ast_string_field_set(user, cid_num, v->value); 09905 ast_set_flag(user, IAX_HASCALLERID); 09906 } else { 09907 ast_string_field_set(user, cid_num, ""); 09908 if (ast_strlen_zero(user->cid_name)) 09909 ast_clear_flag(user, IAX_HASCALLERID); 09910 } 09911 } else if (!strcasecmp(v->name, "accountcode")) { 09912 ast_string_field_set(user, accountcode, v->value); 09913 } else if (!strcasecmp(v->name, "mohinterpret")) { 09914 ast_string_field_set(user, mohinterpret, v->value); 09915 } else if (!strcasecmp(v->name, "mohsuggest")) { 09916 ast_string_field_set(user, mohsuggest, v->value); 09917 } else if (!strcasecmp(v->name, "language")) { 09918 ast_string_field_set(user, language, v->value); 09919 } else if (!strcasecmp(v->name, "amaflags")) { 09920 format = ast_cdr_amaflags2int(v->value); 09921 if (format < 0) { 09922 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 09923 } else { 09924 user->amaflags = format; 09925 } 09926 } else if (!strcasecmp(v->name, "inkeys")) { 09927 ast_string_field_set(user, inkeys, v->value); 09928 } else if (!strcasecmp(v->name, "maxauthreq")) { 09929 user->maxauthreq = atoi(v->value); 09930 if (user->maxauthreq < 0) 09931 user->maxauthreq = 0; 09932 } else if (!strcasecmp(v->name, "adsi")) { 09933 user->adsi = ast_true(v->value); 09934 }/* else if (strcasecmp(v->name,"type")) */ 09935 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09936 v = v->next; 09937 if (!v) { 09938 v = alt; 09939 alt = NULL; 09940 } 09941 } 09942 if (!user->authmethods) { 09943 if (!ast_strlen_zero(user->secret)) { 09944 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09945 if (!ast_strlen_zero(user->inkeys)) 09946 user->authmethods |= IAX_AUTH_RSA; 09947 } else if (!ast_strlen_zero(user->inkeys)) { 09948 user->authmethods = IAX_AUTH_RSA; 09949 } else { 09950 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09951 } 09952 } 09953 ast_clear_flag(user, IAX_DELME); 09954 } 09955 cleanup: 09956 if (oldha) 09957 ast_free_ha(oldha); 09958 if (oldcon) 09959 free_context(oldcon); 09960 return user; 09961 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 10469 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().
10470 { 10471 struct sockaddr_in sin; 10472 int x; 10473 int callno; 10474 struct iax_ie_data ied; 10475 struct create_addr_info cai; 10476 struct parsed_dial_string pds; 10477 char *tmpstr; 10478 10479 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 10480 /* Look for an *exact match* call. Once a call is negotiated, it can only 10481 look up entries for a single context */ 10482 if (!ast_mutex_trylock(&iaxsl[x])) { 10483 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 10484 return x; 10485 ast_mutex_unlock(&iaxsl[x]); 10486 } 10487 } 10488 10489 /* No match found, we need to create a new one */ 10490 10491 memset(&cai, 0, sizeof(cai)); 10492 memset(&ied, 0, sizeof(ied)); 10493 memset(&pds, 0, sizeof(pds)); 10494 10495 tmpstr = ast_strdupa(data); 10496 parse_dial_string(tmpstr, &pds); 10497 10498 if (ast_strlen_zero(pds.peer)) { 10499 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 10500 return -1; 10501 } 10502 10503 /* Populate our address from the given */ 10504 if (create_addr(pds.peer, NULL, &sin, &cai)) 10505 return -1; 10506 10507 if (option_debug) 10508 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n", 10509 pds.peer, pds.username, pds.password, pds.context); 10510 10511 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 10512 if (callno < 1) { 10513 ast_log(LOG_WARNING, "Unable to create call\n"); 10514 return -1; 10515 } 10516 10517 ast_string_field_set(iaxs[callno], dproot, data); 10518 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 10519 10520 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 10521 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 10522 /* the string format is slightly different from a standard dial string, 10523 because the context appears in the 'exten' position 10524 */ 10525 if (pds.exten) 10526 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 10527 if (pds.username) 10528 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 10529 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 10530 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 10531 /* Keep password handy */ 10532 if (pds.password) 10533 ast_string_field_set(iaxs[callno], secret, pds.password); 10534 if (pds.key) 10535 ast_string_field_set(iaxs[callno], outkey, pds.key); 10536 /* Start the call going */ 10537 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 10538 10539 return callno; 10540 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 4160 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.
04161 { 04162 /* Returns where in "receive time" we are. That is, how many ms 04163 since we received (or would have received) the frame with timestamp 0 */ 04164 int ms; 04165 #ifdef IAXTESTS 04166 int jit; 04167 #endif /* IAXTESTS */ 04168 /* Setup rxcore if necessary */ 04169 if (ast_tvzero(p->rxcore)) { 04170 p->rxcore = ast_tvnow(); 04171 if (option_debug && iaxdebug) 04172 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 04173 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 04174 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 04175 #if 1 04176 if (option_debug && iaxdebug) 04177 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 04178 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 04179 #endif 04180 } 04181 04182 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 04183 #ifdef IAXTESTS 04184 if (test_jit) { 04185 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 04186 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 04187 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 04188 jit = -jit; 04189 ms += jit; 04190 } 04191 } 04192 if (test_late) { 04193 ms += test_late; 04194 test_late = 0; 04195 } 04196 #endif /* IAXTESTS */ 04197 return ms; 04198 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 4031 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().
04032 { 04033 int ms; 04034 int voice = 0; 04035 int genuine = 0; 04036 int adjust; 04037 struct timeval *delivery = NULL; 04038 04039 04040 /* What sort of frame do we have?: voice is self-explanatory 04041 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 04042 non-genuine frames are CONTROL frames [ringing etc], DTMF 04043 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 04044 the others need a timestamp slaved to the voice frames so that they go in sequence 04045 */ 04046 if (f) { 04047 if (f->frametype == AST_FRAME_VOICE) { 04048 voice = 1; 04049 delivery = &f->delivery; 04050 } else if (f->frametype == AST_FRAME_IAX) { 04051 genuine = 1; 04052 } else if (f->frametype == AST_FRAME_CNG) { 04053 p->notsilenttx = 0; 04054 } 04055 } 04056 if (ast_tvzero(p->offset)) { 04057 gettimeofday(&p->offset, NULL); 04058 /* Round to nearest 20ms for nice looking traces */ 04059 p->offset.tv_usec -= p->offset.tv_usec % 20000; 04060 } 04061 /* If the timestamp is specified, just send it as is */ 04062 if (ts) 04063 return ts; 04064 /* If we have a time that the frame arrived, always use it to make our timestamp */ 04065 if (delivery && !ast_tvzero(*delivery)) { 04066 ms = ast_tvdiff_ms(*delivery, p->offset); 04067 if (option_debug > 2 && iaxdebug) 04068 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 04069 } else { 04070 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 04071 if (ms < 0) 04072 ms = 0; 04073 if (voice) { 04074 /* On a voice frame, use predicted values if appropriate */ 04075 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 04076 /* Adjust our txcore, keeping voice and non-voice synchronized */ 04077 /* AN EXPLANATION: 04078 When we send voice, we usually send "calculated" timestamps worked out 04079 on the basis of the number of samples sent. When we send other frames, 04080 we usually send timestamps worked out from the real clock. 04081 The problem is that they can tend to drift out of step because the 04082 source channel's clock and our clock may not be exactly at the same rate. 04083 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 04084 for this call. Moving it adjusts timestamps for non-voice frames. 04085 We make the adjustment in the style of a moving average. Each time we 04086 adjust p->offset by 10% of the difference between our clock-derived 04087 timestamp and the predicted timestamp. That's why you see "10000" 04088 below even though IAX2 timestamps are in milliseconds. 04089 The use of a moving average avoids offset moving too radically. 04090 Generally, "adjust" roams back and forth around 0, with offset hardly 04091 changing at all. But if a consistent different starts to develop it 04092 will be eliminated over the course of 10 frames (200-300msecs) 04093 */ 04094 adjust = (ms - p->nextpred); 04095 if (adjust < 0) 04096 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 04097 else if (adjust > 0) 04098 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 04099 04100 if (!p->nextpred) { 04101 p->nextpred = ms; /*f->samples / 8;*/ 04102 if (p->nextpred <= p->lastsent) 04103 p->nextpred = p->lastsent + 3; 04104 } 04105 ms = p->nextpred; 04106 } else { 04107 /* in this case, just use the actual 04108 * time, since we're either way off 04109 * (shouldn't happen), or we're ending a 04110 * silent period -- and seed the next 04111 * predicted time. Also, round ms to the 04112 * next multiple of frame size (so our 04113 * silent periods are multiples of 04114 * frame size too) */ 04115 04116 if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 04117 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 04118 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 04119 04120 if (f->samples >= 8) /* check to make sure we dont core dump */ 04121 { 04122 int diff = ms % (f->samples / 8); 04123 if (diff) 04124 ms += f->samples/8 - diff; 04125 } 04126 04127 p->nextpred = ms; 04128 p->notsilenttx = 1; 04129 } 04130 } else if ( f->frametype == AST_FRAME_VIDEO ) { 04131 /* 04132 * IAX2 draft 03 says that timestamps MUST be in order. 04133 * It does not say anything about several frames having the same timestamp 04134 * When transporting video, we can have a frame that spans multiple iax packets 04135 * (so called slices), so it would make sense to use the same timestamp for all of 04136 * them 04137 * We do want to make sure that frames don't go backwards though 04138 */ 04139 if ( (unsigned int)ms < p->lastsent ) 04140 ms = p->lastsent; 04141 } else { 04142 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 04143 it's a genuine frame */ 04144 if (genuine) { 04145 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 04146 if (ms <= p->lastsent) 04147 ms = p->lastsent + 3; 04148 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 04149 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 04150 ms = p->lastsent + 3; 04151 } 04152 } 04153 } 04154 p->lastsent = ms; 04155 if (voice) 04156 p->nextpred = p->nextpred + f->samples / 8; 04157 return ms; 04158 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | tv | |||
) | [static] |
Definition at line 3987 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().
03988 { 03989 unsigned long int mssincetx; /* unsigned to handle overflows */ 03990 long int ms, pred; 03991 03992 tpeer->trunkact = *tv; 03993 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime); 03994 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 03995 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 03996 tpeer->txtrunktime = *tv; 03997 tpeer->lastsent = 999999; 03998 } 03999 /* Update last transmit time now */ 04000 tpeer->lasttxtime = *tv; 04001 04002 /* Calculate ms offset */ 04003 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime); 04004 /* Predict from last value */ 04005 pred = tpeer->lastsent + sampms; 04006 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 04007 ms = pred; 04008 04009 /* We never send the same timestamp twice, so fudge a little if we must */ 04010 if (ms == tpeer->lastsent) 04011 ms = tpeer->lastsent + 1; 04012 tpeer->lastsent = ms; 04013 return ms; 04014 }
static int check_access | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5271 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().
05272 { 05273 /* Start pessimistic */ 05274 int res = -1; 05275 int version = 2; 05276 struct iax2_user *user = NULL, *best = NULL; 05277 int bestscore = 0; 05278 int gotcapability = 0; 05279 struct ast_variable *v = NULL, *tmpvar = NULL; 05280 struct ao2_iterator i; 05281 05282 if (!iaxs[callno]) 05283 return res; 05284 if (ies->called_number) 05285 ast_string_field_set(iaxs[callno], exten, ies->called_number); 05286 if (ies->calling_number) { 05287 ast_shrink_phone_number(ies->calling_number); 05288 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 05289 } 05290 if (ies->calling_name) 05291 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 05292 if (ies->calling_ani) 05293 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 05294 if (ies->dnid) 05295 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 05296 if (ies->rdnis) 05297 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 05298 if (ies->called_context) 05299 ast_string_field_set(iaxs[callno], context, ies->called_context); 05300 if (ies->language) 05301 ast_string_field_set(iaxs[callno], language, ies->language); 05302 if (ies->username) 05303 ast_string_field_set(iaxs[callno], username, ies->username); 05304 if (ies->calling_ton > -1) 05305 iaxs[callno]->calling_ton = ies->calling_ton; 05306 if (ies->calling_tns > -1) 05307 iaxs[callno]->calling_tns = ies->calling_tns; 05308 if (ies->calling_pres > -1) 05309 iaxs[callno]->calling_pres = ies->calling_pres; 05310 if (ies->format) 05311 iaxs[callno]->peerformat = ies->format; 05312 if (ies->adsicpe) 05313 iaxs[callno]->peeradsicpe = ies->adsicpe; 05314 if (ies->capability) { 05315 gotcapability = 1; 05316 iaxs[callno]->peercapability = ies->capability; 05317 } 05318 if (ies->version) 05319 version = ies->version; 05320 05321 /* Use provided preferences until told otherwise for actual preferences */ 05322 if(ies->codec_prefs) { 05323 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 05324 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 05325 } 05326 05327 if (!gotcapability) 05328 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 05329 if (version > IAX_PROTO_VERSION) { 05330 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 05331 ast_inet_ntoa(sin->sin_addr), version); 05332 return res; 05333 } 05334 /* Search the userlist for a compatible entry, and fill in the rest */ 05335 i = ao2_iterator_init(users, 0); 05336 while ((user = ao2_iterator_next(&i))) { 05337 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 05338 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 05339 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 05340 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 05341 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 05342 if (!ast_strlen_zero(iaxs[callno]->username)) { 05343 /* Exact match, stop right now. */ 05344 if (best) 05345 user_unref(best); 05346 best = user; 05347 break; 05348 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 05349 /* No required authentication */ 05350 if (user->ha) { 05351 /* There was host authentication and we passed, bonus! */ 05352 if (bestscore < 4) { 05353 bestscore = 4; 05354 if (best) 05355 user_unref(best); 05356 best = user; 05357 continue; 05358 } 05359 } else { 05360 /* No host access, but no secret, either, not bad */ 05361 if (bestscore < 3) { 05362 bestscore = 3; 05363 if (best) 05364 user_unref(best); 05365 best = user; 05366 continue; 05367 } 05368 } 05369 } else { 05370 if (user->ha) { 05371 /* Authentication, but host access too, eh, it's something.. */ 05372 if (bestscore < 2) { 05373 bestscore = 2; 05374 if (best) 05375 user_unref(best); 05376 best = user; 05377 continue; 05378 } 05379 } else { 05380 /* Authentication and no host access... This is our baseline */ 05381 if (bestscore < 1) { 05382 bestscore = 1; 05383 if (best) 05384 user_unref(best); 05385 best = user; 05386 continue; 05387 } 05388 } 05389 } 05390 } 05391 user_unref(user); 05392 } 05393 user = best; 05394 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 05395 user = realtime_user(iaxs[callno]->username, sin); 05396 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 05397 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 05398 user = user_unref(user); 05399 } 05400 } 05401 if (user) { 05402 /* We found our match (use the first) */ 05403 /* copy vars */ 05404 for (v = user->vars ; v ; v = v->next) { 05405 if((tmpvar = ast_variable_new(v->name, v->value))) { 05406 tmpvar->next = iaxs[callno]->vars; 05407 iaxs[callno]->vars = tmpvar; 05408 } 05409 } 05410 /* If a max AUTHREQ restriction is in place, activate it */ 05411 if (user->maxauthreq > 0) 05412 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ); 05413 iaxs[callno]->prefs = user->prefs; 05414 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST); 05415 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS); 05416 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP); 05417 iaxs[callno]->encmethods = user->encmethods; 05418 /* Store the requested username if not specified */ 05419 if (ast_strlen_zero(iaxs[callno]->username)) 05420 ast_string_field_set(iaxs[callno], username, user->name); 05421 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 05422 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 05423 iaxs[callno]->capability = user->capability; 05424 /* And use the default context */ 05425 if (ast_strlen_zero(iaxs[callno]->context)) { 05426 if (user->contexts) 05427 ast_string_field_set(iaxs[callno], context, user->contexts->context); 05428 else 05429 ast_string_field_set(iaxs[callno], context, context); 05430 } 05431 /* And any input keys */ 05432 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 05433 /* And the permitted authentication methods */ 05434 iaxs[callno]->authmethods = user->authmethods; 05435 iaxs[callno]->adsi = user->adsi; 05436 /* If the user has callerid, override the remote caller id. */ 05437 if (ast_test_flag(user, IAX_HASCALLERID)) { 05438 iaxs[callno]->calling_tns = 0; 05439 iaxs[callno]->calling_ton = 0; 05440 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 05441 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 05442 ast_string_field_set(iaxs[callno], ani, user->cid_num); 05443 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 05444 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) { 05445 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 05446 } /* else user is allowed to set their own CID settings */ 05447 if (!ast_strlen_zero(user->accountcode)) 05448 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 05449 if (!ast_strlen_zero(user->mohinterpret)) 05450 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 05451 if (!ast_strlen_zero(user->mohsuggest)) 05452 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 05453 if (user->amaflags) 05454 iaxs[callno]->amaflags = user->amaflags; 05455 if (!ast_strlen_zero(user->language)) 05456 ast_string_field_set(iaxs[callno], language, user->language); 05457 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 05458 /* Keep this check last */ 05459 if (!ast_strlen_zero(user->dbsecret)) { 05460 char *family, *key=NULL; 05461 char buf[80]; 05462 family = ast_strdupa(user->dbsecret); 05463 key = strchr(family, '/'); 05464 if (key) { 05465 *key = '\0'; 05466 key++; 05467 } 05468 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 05469 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 05470 else 05471 ast_string_field_set(iaxs[callno], secret, buf); 05472 } else 05473 ast_string_field_set(iaxs[callno], secret, user->secret); 05474 res = 0; 05475 user = user_unref(user); 05476 } 05477 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 05478 return res; 05479 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 6972 of file chan_iax2.c.
References ast_log(), iax2_provision(), iax_provision_version(), and option_debug.
Referenced by socket_process().
06973 { 06974 unsigned int ourver; 06975 char rsi[80]; 06976 snprintf(rsi, sizeof(rsi), "si-%s", si); 06977 if (iax_provision_version(&ourver, rsi, 1)) 06978 return 0; 06979 if (option_debug) 06980 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 06981 if (ourver != ver) 06982 iax2_provision(sin, sockfd, NULL, rsi, 1); 06983 return 0; 06984 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 9397 of file chan_iax2.c.
References ast_log(), errno, LOG_ERROR, and option_debug.
Referenced by peer_set_srcaddr().
09398 { 09399 int sd; 09400 int res; 09401 09402 sd = socket(AF_INET, SOCK_DGRAM, 0); 09403 if (sd < 0) { 09404 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 09405 return -1; 09406 } 09407 09408 res = bind(sd, sa, salen); 09409 if (res < 0) { 09410 if (option_debug) 09411 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno)); 09412 close(sd); 09413 return 1; 09414 } 09415 09416 close(sd); 09417 return 0; 09418 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5965 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().
05966 { 05967 char exten[256] = ""; 05968 int status = CACHE_FLAG_UNKNOWN; 05969 int expiry = iaxdefaultdpcache; 05970 int x; 05971 int matchmore = 0; 05972 struct iax2_dpcache *dp, *prev; 05973 05974 if (ies->called_number) 05975 ast_copy_string(exten, ies->called_number, sizeof(exten)); 05976 05977 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 05978 status = CACHE_FLAG_EXISTS; 05979 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 05980 status = CACHE_FLAG_CANEXIST; 05981 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 05982 status = CACHE_FLAG_NONEXISTENT; 05983 05984 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) { 05985 /* Don't really do anything with this */ 05986 } 05987 if (ies->refresh) 05988 expiry = ies->refresh; 05989 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 05990 matchmore = CACHE_FLAG_MATCHMORE; 05991 ast_mutex_lock(&dpcache_lock); 05992 prev = NULL; 05993 dp = pvt->dpentries; 05994 while(dp) { 05995 if (!strcmp(dp->exten, exten)) { 05996 /* Let them go */ 05997 if (prev) 05998 prev->peer = dp->peer; 05999 else 06000 pvt->dpentries = dp->peer; 06001 dp->peer = NULL; 06002 dp->callno = 0; 06003 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 06004 if (dp->flags & CACHE_FLAG_PENDING) { 06005 dp->flags &= ~CACHE_FLAG_PENDING; 06006 dp->flags |= status; 06007 dp->flags |= matchmore; 06008 } 06009 /* Wake up waiters */ 06010 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 06011 if (dp->waiters[x] > -1) { 06012 if (write(dp->waiters[x], "asdf", 4) < 0) { 06013 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 06014 } 06015 } 06016 } 06017 } 06018 prev = dp; 06019 dp = dp->peer; 06020 } 06021 ast_mutex_unlock(&dpcache_lock); 06022 return 0; 06023 }
static char* complete_iax2_show_peer | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2527 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_strdup, iax2_peer::name, and peer_unref().
02528 { 02529 int which = 0; 02530 struct iax2_peer *peer; 02531 char *res = NULL; 02532 int wordlen = strlen(word); 02533 struct ao2_iterator i; 02534 02535 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */ 02536 if (pos != 3) 02537 return NULL; 02538 02539 i = ao2_iterator_init(peers, 0); 02540 while ((peer = ao2_iterator_next(&i))) { 02541 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) { 02542 res = ast_strdup(peer->name); 02543 peer_unref(peer); 02544 break; 02545 } 02546 peer_unref(peer); 02547 } 02548 02549 return res; 02550 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 6025 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(), remove_by_transfercallno(), 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().
06026 { 06027 int peercallno = 0; 06028 struct chan_iax2_pvt *pvt = iaxs[callno]; 06029 struct iax_frame *cur; 06030 jb_frame frame; 06031 06032 if (ies->callno) 06033 peercallno = ies->callno; 06034 06035 if (peercallno < 1) { 06036 ast_log(LOG_WARNING, "Invalid transfer request\n"); 06037 return -1; 06038 } 06039 remove_by_transfercallno(pvt); 06040 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 06041 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 06042 /* Reset sequence numbers */ 06043 pvt->oseqno = 0; 06044 pvt->rseqno = 0; 06045 pvt->iseqno = 0; 06046 pvt->aseqno = 0; 06047 06048 if (pvt->peercallno) { 06049 remove_by_peercallno(pvt); 06050 } 06051 pvt->peercallno = peercallno; 06052 /*this is where the transfering call swiches hash tables */ 06053 store_by_peercallno(pvt); 06054 pvt->transferring = TRANSFER_NONE; 06055 pvt->svoiceformat = -1; 06056 pvt->voiceformat = 0; 06057 pvt->svideoformat = -1; 06058 pvt->videoformat = 0; 06059 pvt->transfercallno = -1; 06060 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 06061 memset(&pvt->offset, 0, sizeof(pvt->offset)); 06062 /* reset jitterbuffer */ 06063 while(jb_getall(pvt->jb,&frame) == JB_OK) 06064 iax2_frame_free(frame.data); 06065 jb_reset(pvt->jb); 06066 pvt->lag = 0; 06067 pvt->last = 0; 06068 pvt->lastsent = 0; 06069 pvt->nextpred = 0; 06070 pvt->pingtime = DEFAULT_RETRY_TIME; 06071 AST_LIST_LOCK(&iaxq.queue); 06072 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 06073 /* We must cancel any packets that would have been transmitted 06074 because now we're talking to someone new. It's okay, they 06075 were transmitted to someone that didn't care anyway. */ 06076 if (callno == cur->callno) 06077 cur->retries = -1; 06078 } 06079 AST_LIST_UNLOCK(&iaxq.queue); 06080 return 0; 06081 }
static unsigned char compress_subclass | ( | int | subclass | ) | [static] |
Definition at line 1083 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().
01084 { 01085 int x; 01086 int power=-1; 01087 /* If it's 128 or smaller, just return it */ 01088 if (subclass < IAX_FLAG_SC_LOG) 01089 return subclass; 01090 /* Otherwise find its power */ 01091 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01092 if (subclass & (1 << x)) { 01093 if (power > -1) { 01094 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 01095 return 0; 01096 } else 01097 power = x; 01098 } 01099 } 01100 return power | IAX_FLAG_SC_LOG; 01101 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 6986 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().
06987 { 06988 jb_info stats; 06989 jb_getinfo(pvt->jb, &stats); 06990 06991 memset(iep, 0, sizeof(*iep)); 06992 06993 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 06994 if(stats.frames_in == 0) stats.frames_in = 1; 06995 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 06996 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 06997 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 06998 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 06999 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 07000 }
static int create_addr | ( | const char * | peername, | |
struct ast_channel * | c, | |||
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 3150 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.
03151 { 03152 struct ast_hostent ahp; 03153 struct hostent *hp; 03154 struct iax2_peer *peer; 03155 int res = -1; 03156 struct ast_codec_pref ourprefs; 03157 03158 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 03159 cai->sockfd = defaultsockfd; 03160 cai->maxtime = 0; 03161 sin->sin_family = AF_INET; 03162 03163 if (!(peer = find_peer(peername, 1))) { 03164 cai->found = 0; 03165 03166 hp = ast_gethostbyname(peername, &ahp); 03167 if (hp) { 03168 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 03169 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 03170 /* use global iax prefs for unknown peer/user */ 03171 /* But move the calling channel's native codec to the top of the preference list */ 03172 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 03173 if (c) 03174 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 03175 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 03176 return 0; 03177 } else { 03178 ast_log(LOG_WARNING, "No such host: %s\n", peername); 03179 return -1; 03180 } 03181 } 03182 03183 cai->found = 1; 03184 03185 /* if the peer has no address (current or default), return failure */ 03186 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) 03187 goto return_unref; 03188 03189 /* if the peer is being monitored and is currently unreachable, return failure */ 03190 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 03191 goto return_unref; 03192 03193 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 03194 cai->maxtime = peer->maxms; 03195 cai->capability = peer->capability; 03196 cai->encmethods = peer->encmethods; 03197 cai->sockfd = peer->sockfd; 03198 cai->adsi = peer->adsi; 03199 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 03200 /* Move the calling channel's native codec to the top of the preference list */ 03201 if (c) { 03202 ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats); 03203 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 03204 } 03205 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 03206 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 03207 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 03208 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 03209 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 03210 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 03211 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 03212 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 03213 if (ast_strlen_zero(peer->dbsecret)) { 03214 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 03215 } else { 03216 char *family; 03217 char *key = NULL; 03218 03219 family = ast_strdupa(peer->dbsecret); 03220 key = strchr(family, '/'); 03221 if (key) 03222 *key++ = '\0'; 03223 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 03224 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 03225 goto return_unref; 03226 } 03227 } 03228 03229 if (peer->addr.sin_addr.s_addr) { 03230 sin->sin_addr = peer->addr.sin_addr; 03231 sin->sin_port = peer->addr.sin_port; 03232 } else { 03233 sin->sin_addr = peer->defaddr.sin_addr; 03234 sin->sin_port = peer->defaddr.sin_port; 03235 } 03236 03237 res = 0; 03238 03239 return_unref: 03240 peer_unref(peer); 03241 03242 return res; 03243 }
static int decode_frame | ( | aes_decrypt_ctx * | dcx, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 4346 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().
04347 { 04348 int padding; 04349 unsigned char *workspace; 04350 04351 workspace = alloca(*datalen); 04352 memset(f, 0, sizeof(*f)); 04353 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 04354 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 04355 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 04356 return -1; 04357 /* Decrypt */ 04358 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 04359 04360 padding = 16 + (workspace[15] & 0xf); 04361 if (option_debug && iaxdebug) 04362 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 04363 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 04364 return -1; 04365 04366 *datalen -= padding; 04367 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 04368 f->frametype = fh->type; 04369 if (f->frametype == AST_FRAME_VIDEO) { 04370 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 04371 } else { 04372 f->subclass = uncompress_subclass(fh->csub); 04373 } 04374 } else { 04375 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 04376 if (option_debug && iaxdebug) 04377 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen); 04378 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 04379 return -1; 04380 /* Decrypt */ 04381 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 04382 padding = 16 + (workspace[15] & 0x0f); 04383 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 04384 return -1; 04385 *datalen -= padding; 04386 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04387 } 04388 return 0; 04389 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 4432 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().
04433 { 04434 int res=-1; 04435 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 04436 /* Search for possible keys, given secrets */ 04437 struct MD5Context md5; 04438 unsigned char digest[16]; 04439 char *tmppw, *stringp; 04440 04441 tmppw = ast_strdupa(iaxs[callno]->secret); 04442 stringp = tmppw; 04443 while ((tmppw = strsep(&stringp, ";"))) { 04444 MD5Init(&md5); 04445 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 04446 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 04447 MD5Final(digest, &md5); 04448 build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx); 04449 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04450 if (!res) { 04451 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 04452 break; 04453 } 04454 } 04455 } else 04456 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04457 return res; 04458 }
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 7048 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().
07049 { 07050 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 07051 struct ast_iax2_full_hdr *fh, *cur_fh; 07052 07053 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 07054 return; 07055 07056 pkt_buf->len = from_here->buf_len; 07057 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 07058 07059 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 07060 ast_mutex_lock(&to_here->lock); 07061 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 07062 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 07063 if (fh->oseqno < cur_fh->oseqno) { 07064 AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry); 07065 break; 07066 } 07067 } 07068 AST_LIST_TRAVERSE_SAFE_END 07069 07070 if (!cur_pkt_buf) 07071 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 07072 07073 ast_mutex_unlock(&to_here->lock); 07074 }
static void delete_users | ( | void | ) | [static] |
Definition at line 9981 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().
09982 { 09983 struct iax2_registry *reg; 09984 09985 ao2_callback(users, 0, user_delme_cb, NULL); 09986 09987 AST_LIST_LOCK(®istrations); 09988 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 09989 ast_sched_del(sched, reg->expire); 09990 if (reg->callno) { 09991 int callno = reg->callno; 09992 ast_mutex_lock(&iaxsl[callno]); 09993 if (iaxs[callno]) { 09994 iaxs[callno]->reg = NULL; 09995 iax2_destroy(callno); 09996 } 09997 ast_mutex_unlock(&iaxsl[callno]); 09998 } 09999 if (reg->dnsmgr) 10000 ast_dnsmgr_release(reg->dnsmgr); 10001 free(reg); 10002 } 10003 AST_LIST_UNLOCK(®istrations); 10004 10005 ao2_callback(peers, 0, peer_delme_cb, NULL); 10006 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 1860 of file chan_iax2.c.
References ast_iax2_firmware_header::datalen, iax_firmware::fd, free, and iax_firmware::fwh.
Referenced by reload_firmware().
01861 { 01862 /* Close firmware */ 01863 if (cur->fwh) { 01864 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 01865 } 01866 close(cur->fd); 01867 free(cur); 01868 }
static void dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 6820 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().
06821 { 06822 unsigned short dpstatus = 0; 06823 struct iax_ie_data ied1; 06824 int mm; 06825 06826 memset(&ied1, 0, sizeof(ied1)); 06827 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 06828 /* Must be started */ 06829 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 06830 dpstatus = IAX_DPSTATUS_EXISTS; 06831 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 06832 dpstatus = IAX_DPSTATUS_CANEXIST; 06833 } else { 06834 dpstatus = IAX_DPSTATUS_NONEXISTENT; 06835 } 06836 if (ast_ignore_pattern(context, callednum)) 06837 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 06838 if (mm) 06839 dpstatus |= IAX_DPSTATUS_MATCHMORE; 06840 if (!skiplock) 06841 ast_mutex_lock(&iaxsl[callno]); 06842 if (iaxs[callno]) { 06843 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 06844 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 06845 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 06846 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 06847 } 06848 if (!skiplock) 06849 ast_mutex_unlock(&iaxsl[callno]); 06850 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 6852 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().
06853 { 06854 /* Look up for dpreq */ 06855 struct dpreq_data *dpr = data; 06856 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 06857 if (dpr->callerid) 06858 free(dpr->callerid); 06859 free(dpr); 06860 return NULL; 06861 }
static int encrypt_frame | ( | aes_encrypt_ctx * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 4391 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().
04392 { 04393 int padding; 04394 unsigned char *workspace; 04395 workspace = alloca(*datalen + 32); 04396 if (!workspace) 04397 return -1; 04398 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 04399 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 04400 if (option_debug && iaxdebug) 04401 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 04402 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 04403 padding = 16 + (padding & 0xf); 04404 memcpy(workspace, poo, padding); 04405 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 04406 workspace[15] &= 0xf0; 04407 workspace[15] |= (padding & 0xf); 04408 if (option_debug && iaxdebug) 04409 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]); 04410 *datalen += padding; 04411 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 04412 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 04413 memcpy(poo, workspace + *datalen - 32, 32); 04414 } else { 04415 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 04416 if (option_debug && iaxdebug) 04417 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen); 04418 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 04419 padding = 16 + (padding & 0xf); 04420 memcpy(workspace, poo, padding); 04421 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04422 workspace[15] &= 0xf0; 04423 workspace[15] |= (padding & 0x0f); 04424 *datalen += padding; 04425 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 04426 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 04427 memcpy(poo, workspace + *datalen - 32, 32); 04428 } 04429 return 0; 04430 }
static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 6263 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by iax2_prune_realtime(), reg_source_db(), and update_registry().
06264 { 06265 #ifdef SCHED_MULTITHREADED 06266 if (schedule_action(__expire_registry, data)) 06267 #endif 06268 __expire_registry(data); 06269 return 0; 06270 }
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 10542 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().
10543 { 10544 struct iax2_dpcache *dp, *prev = NULL, *next; 10545 struct timeval tv; 10546 int x; 10547 int com[2]; 10548 int timeout; 10549 int old=0; 10550 int outfd; 10551 int abort; 10552 int callno; 10553 struct ast_channel *c; 10554 struct ast_frame *f; 10555 gettimeofday(&tv, NULL); 10556 dp = dpcache; 10557 while(dp) { 10558 next = dp->next; 10559 /* Expire old caches */ 10560 if (ast_tvcmp(tv, dp->expiry) > 0) { 10561 /* It's expired, let it disappear */ 10562 if (prev) 10563 prev->next = dp->next; 10564 else 10565 dpcache = dp->next; 10566 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) { 10567 /* Free memory and go again */ 10568 free(dp); 10569 } else { 10570 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); 10571 } 10572 dp = next; 10573 continue; 10574 } 10575 /* We found an entry that matches us! */ 10576 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 10577 break; 10578 prev = dp; 10579 dp = next; 10580 } 10581 if (!dp) { 10582 /* No matching entry. Create a new one. */ 10583 /* First, can we make a callno? */ 10584 callno = cache_get_callno_locked(data); 10585 if (callno < 0) { 10586 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 10587 return NULL; 10588 } 10589 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 10590 ast_mutex_unlock(&iaxsl[callno]); 10591 return NULL; 10592 } 10593 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 10594 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 10595 gettimeofday(&dp->expiry, NULL); 10596 dp->orig = dp->expiry; 10597 /* Expires in 30 mins by default */ 10598 dp->expiry.tv_sec += iaxdefaultdpcache; 10599 dp->next = dpcache; 10600 dp->flags = CACHE_FLAG_PENDING; 10601 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 10602 dp->waiters[x] = -1; 10603 dpcache = dp; 10604 dp->peer = iaxs[callno]->dpentries; 10605 iaxs[callno]->dpentries = dp; 10606 /* Send the request if we're already up */ 10607 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 10608 iax2_dprequest(dp, callno); 10609 ast_mutex_unlock(&iaxsl[callno]); 10610 } 10611 /* By here we must have a dp */ 10612 if (dp->flags & CACHE_FLAG_PENDING) { 10613 /* Okay, here it starts to get nasty. We need a pipe now to wait 10614 for a reply to come back so long as it's pending */ 10615 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) { 10616 /* Find an empty slot */ 10617 if (dp->waiters[x] < 0) 10618 break; 10619 } 10620 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) { 10621 ast_log(LOG_WARNING, "No more waiter positions available\n"); 10622 return NULL; 10623 } 10624 if (pipe(com)) { 10625 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 10626 return NULL; 10627 } 10628 dp->waiters[x] = com[1]; 10629 /* Okay, now we wait */ 10630 timeout = iaxdefaulttimeout * 1000; 10631 /* Temporarily unlock */ 10632 ast_mutex_unlock(&dpcache_lock); 10633 /* Defer any dtmf */ 10634 if (chan) 10635 old = ast_channel_defer_dtmf(chan); 10636 abort = 0; 10637 while(timeout) { 10638 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 10639 if (outfd > -1) { 10640 break; 10641 } 10642 if (c) { 10643 f = ast_read(c); 10644 if (f) 10645 ast_frfree(f); 10646 else { 10647 /* Got hung up on, abort! */ 10648 break; 10649 abort = 1; 10650 } 10651 } 10652 } 10653 if (!timeout) { 10654 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 10655 } 10656 ast_mutex_lock(&dpcache_lock); 10657 dp->waiters[x] = -1; 10658 close(com[1]); 10659 close(com[0]); 10660 if (abort) { 10661 /* Don't interpret anything, just abort. Not sure what th epoint 10662 of undeferring dtmf on a hung up channel is but hey whatever */ 10663 if (!old && chan) 10664 ast_channel_undefer_dtmf(chan); 10665 return NULL; 10666 } 10667 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 10668 /* Now to do non-independent analysis the results of our wait */ 10669 if (dp->flags & CACHE_FLAG_PENDING) { 10670 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 10671 pending. Don't let it take as long to timeout. */ 10672 dp->flags &= ~CACHE_FLAG_PENDING; 10673 dp->flags |= CACHE_FLAG_TIMEOUT; 10674 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 10675 systems without leaving it unavailable once the server comes back online */ 10676 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 10677 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 10678 if (dp->waiters[x] > -1) { 10679 if (write(dp->waiters[x], "asdf", 4) < 0) { 10680 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 10681 } 10682 } 10683 } 10684 } 10685 } 10686 /* Our caller will obtain the rest */ 10687 if (!old && chan) 10688 ast_channel_undefer_dtmf(chan); 10689 } 10690 return dp; 10691 }
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 1760 of file chan_iax2.c.
References __find_callno().
Referenced by iax2_poke_peer(), and socket_process().
01760 { 01761 01762 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame); 01763 }
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 1765 of file chan_iax2.c.
References __find_callno().
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_provision(), iax2_request(), and socket_process().
01765 { 01766 01767 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame); 01768 }
static struct iax2_thread* find_idle_thread | ( | void | ) | [static] |
Definition at line 916 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().
00917 { 00918 pthread_attr_t attr; 00919 struct iax2_thread *thread = NULL; 00920 00921 /* Pop the head of the list off */ 00922 AST_LIST_LOCK(&idle_list); 00923 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 00924 AST_LIST_UNLOCK(&idle_list); 00925 00926 /* If no idle thread is available from the regular list, try dynamic */ 00927 if (thread == NULL) { 00928 AST_LIST_LOCK(&dynamic_list); 00929 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 00930 /* Make sure we absolutely have a thread... if not, try to make one if allowed */ 00931 if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) { 00932 /* We need to MAKE a thread! */ 00933 if ((thread = ast_calloc(1, sizeof(*thread)))) { 00934 thread->threadnum = iaxdynamicthreadnum++; 00935 thread->type = IAX_TYPE_DYNAMIC; 00936 ast_mutex_init(&thread->lock); 00937 ast_cond_init(&thread->cond, NULL); 00938 pthread_attr_init(&attr); 00939 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 00940 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 00941 free(thread); 00942 thread = NULL; 00943 } else { 00944 /* All went well and the thread is up, so increment our count */ 00945 iaxdynamicthreadcount++; 00946 00947 /* Wait for the thread to be ready before returning it to the caller */ 00948 while (!thread->ready_for_signal) 00949 usleep(1); 00950 } 00951 } 00952 } 00953 AST_LIST_UNLOCK(&dynamic_list); 00954 } 00955 00956 /* this thread is not processing a full frame (since it is idle), 00957 so ensure that the field for the full frame call number is empty */ 00958 if (thread) 00959 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 00960 00961 return thread; 00962 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static] |
Definition at line 1161 of file chan_iax2.c.
References ao2_find(), iax2_peer::name, and realtime_peer().
01162 { 01163 struct iax2_peer *peer = NULL; 01164 struct iax2_peer tmp_peer = { 01165 .name = name, 01166 }; 01167 01168 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01169 01170 /* Now go for realtime if applicable */ 01171 if(!peer && realtime) 01172 peer = realtime_peer(name, NULL); 01173 01174 return peer; 01175 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static] |
Definition at line 4200 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().
04201 { 04202 struct iax2_trunk_peer *tpeer; 04203 04204 /* Finds and locks trunk peer */ 04205 ast_mutex_lock(&tpeerlock); 04206 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) { 04207 /* We don't lock here because tpeer->addr *never* changes */ 04208 if (!inaddrcmp(&tpeer->addr, sin)) { 04209 ast_mutex_lock(&tpeer->lock); 04210 break; 04211 } 04212 } 04213 if (!tpeer) { 04214 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 04215 ast_mutex_init(&tpeer->lock); 04216 tpeer->lastsent = 9999; 04217 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 04218 tpeer->trunkact = ast_tvnow(); 04219 ast_mutex_lock(&tpeer->lock); 04220 tpeer->next = tpeers; 04221 tpeer->sockfd = fd; 04222 tpeers = tpeer; 04223 #ifdef SO_NO_CHECK 04224 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 04225 #endif 04226 if (option_debug) 04227 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 04228 } 04229 } 04230 ast_mutex_unlock(&tpeerlock); 04231 return tpeer; 04232 }
static struct iax2_user* find_user | ( | const char * | name | ) | [static] |
Definition at line 1189 of file chan_iax2.c.
References ao2_find(), and iax2_user::name.
01190 { 01191 struct iax2_user tmp_user = { 01192 .name = name, 01193 }; 01194 01195 return ao2_find(users, &tmp_user, OBJ_POINTER); 01196 }
static unsigned int fix_peerts | ( | struct timeval * | tv, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 4016 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvzero(), iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process().
04017 { 04018 long ms; /* NOT unsigned */ 04019 if (ast_tvzero(iaxs[callno]->rxcore)) { 04020 /* Initialize rxcore time if appropriate */ 04021 gettimeofday(&iaxs[callno]->rxcore, NULL); 04022 /* Round to nearest 20ms so traces look pretty */ 04023 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 04024 } 04025 /* Calculate difference between trunk and channel */ 04026 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore); 04027 /* Return as the sum of trunk time and the difference between trunk and real time */ 04028 return ms + ts; 04029 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 9149 of file chan_iax2.c.
References free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
09150 { 09151 struct iax2_context *conl; 09152 while(con) { 09153 conl = con; 09154 con = con->next; 09155 free(conl); 09156 } 09157 }
static int function_iaxpeer | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 10815 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.
10816 { 10817 struct iax2_peer *peer; 10818 char *peername, *colname; 10819 10820 peername = ast_strdupa(data); 10821 10822 /* if our channel, return the IP address of the endpoint of current channel */ 10823 if (!strcmp(peername,"CURRENTCHANNEL")) { 10824 unsigned short callno; 10825 if (chan->tech != &iax2_tech) 10826 return -1; 10827 callno = PTR_TO_CALLNO(chan->tech_pvt); 10828 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 10829 return 0; 10830 } 10831 10832 if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */ 10833 *colname++ = '\0'; 10834 else if ((colname = strchr(peername, '|'))) 10835 *colname++ = '\0'; 10836 else 10837 colname = "ip"; 10838 10839 if (!(peer = find_peer(peername, 1))) 10840 return -1; 10841 10842 if (!strcasecmp(colname, "ip")) { 10843 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 10844 } else if (!strcasecmp(colname, "status")) { 10845 peer_status(peer, buf, len); 10846 } else if (!strcasecmp(colname, "mailbox")) { 10847 ast_copy_string(buf, peer->mailbox, len); 10848 } else if (!strcasecmp(colname, "context")) { 10849 ast_copy_string(buf, peer->context, len); 10850 } else if (!strcasecmp(colname, "expire")) { 10851 snprintf(buf, len, "%d", peer->expire); 10852 } else if (!strcasecmp(colname, "dynamic")) { 10853 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 10854 } else if (!strcasecmp(colname, "callerid_name")) { 10855 ast_copy_string(buf, peer->cid_name, len); 10856 } else if (!strcasecmp(colname, "callerid_num")) { 10857 ast_copy_string(buf, peer->cid_num, len); 10858 } else if (!strcasecmp(colname, "codecs")) { 10859 ast_getformatname_multiple(buf, len -1, peer->capability); 10860 } else if (!strncasecmp(colname, "codec[", 6)) { 10861 char *codecnum, *ptr; 10862 int index = 0, codec = 0; 10863 10864 codecnum = strchr(colname, '['); 10865 *codecnum = '\0'; 10866 codecnum++; 10867 if ((ptr = strchr(codecnum, ']'))) { 10868 *ptr = '\0'; 10869 } 10870 index = atoi(codecnum); 10871 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 10872 ast_copy_string(buf, ast_getformatname(codec), len); 10873 } else { 10874 buf[0] = '\0'; 10875 } 10876 } else { 10877 buf[0] = '\0'; 10878 } 10879 10880 peer_unref(peer); 10881 10882 return 0; 10883 }
static int get_auth_methods | ( | char * | value | ) | [static] |
Definition at line 9381 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
09382 { 09383 int methods = 0; 09384 if (strstr(value, "rsa")) 09385 methods |= IAX_AUTH_RSA; 09386 if (strstr(value, "md5")) 09387 methods |= IAX_AUTH_MD5; 09388 if (strstr(value, "plaintext")) 09389 methods |= IAX_AUTH_PLAINTEXT; 09390 return methods; 09391 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1038 of file chan_iax2.c.
References ast_true(), and IAX_ENCRYPT_AES128.
Referenced by build_peer(), build_user(), and set_config().
01039 { 01040 int e; 01041 if (!strcasecmp(s, "aes128")) 01042 e = IAX_ENCRYPT_AES128; 01043 else if (ast_true(s)) 01044 e = IAX_ENCRYPT_AES128; 01045 else 01046 e = 0; 01047 return e; 01048 }
static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 2764 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
02765 { 02766 #ifdef SCHED_MULTITHREADED 02767 if (schedule_action(__get_from_jb, data)) 02768 #endif 02769 __get_from_jb(data); 02770 return 0; 02771 }
static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 7018 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.
07019 { 07020 struct iax2_pkt_buf *pkt_buf; 07021 07022 ast_mutex_lock(&thread->lock); 07023 07024 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 07025 ast_mutex_unlock(&thread->lock); 07026 07027 thread->buf = pkt_buf->buf; 07028 thread->buf_len = pkt_buf->len; 07029 thread->buf_size = pkt_buf->len + 1; 07030 07031 socket_process(thread); 07032 07033 thread->buf = NULL; 07034 ast_free(pkt_buf); 07035 07036 ast_mutex_lock(&thread->lock); 07037 } 07038 07039 ast_mutex_unlock(&thread->lock); 07040 }
static int handle_error | ( | void | ) | [static] |
Definition at line 2148 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().
02149 { 02150 /* XXX Ideally we should figure out why an error occured and then abort those 02151 rather than continuing to try. Unfortunately, the published interface does 02152 not seem to work XXX */ 02153 #if 0 02154 struct sockaddr_in *sin; 02155 int res; 02156 struct msghdr m; 02157 struct sock_extended_err e; 02158 m.msg_name = NULL; 02159 m.msg_namelen = 0; 02160 m.msg_iov = NULL; 02161 m.msg_control = &e; 02162 m.msg_controllen = sizeof(e); 02163 m.msg_flags = 0; 02164 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 02165 if (res < 0) 02166 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 02167 else { 02168 if (m.msg_controllen) { 02169 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 02170 if (sin) 02171 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 02172 else 02173 ast_log(LOG_WARNING, "No address detected??\n"); 02174 } else { 02175 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 02176 } 02177 } 02178 #endif 02179 return 0; 02180 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 6084 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().
06085 { 06086 struct iax2_registry *reg; 06087 /* Start pessimistic */ 06088 char peer[256] = ""; 06089 char msgstatus[60]; 06090 int refresh = 60; 06091 char ourip[256] = "<Unspecified>"; 06092 struct sockaddr_in oldus; 06093 struct sockaddr_in us; 06094 int oldmsgs; 06095 06096 memset(&us, 0, sizeof(us)); 06097 if (ies->apparent_addr) 06098 bcopy(ies->apparent_addr, &us, sizeof(us)); 06099 if (ies->username) 06100 ast_copy_string(peer, ies->username, sizeof(peer)); 06101 if (ies->refresh) 06102 refresh = ies->refresh; 06103 if (ies->calling_number) { 06104 /* We don't do anything with it really, but maybe we should */ 06105 } 06106 reg = iaxs[callno]->reg; 06107 if (!reg) { 06108 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 06109 return -1; 06110 } 06111 memcpy(&oldus, ®->us, sizeof(oldus)); 06112 oldmsgs = reg->messages; 06113 if (inaddrcmp(®->addr, sin)) { 06114 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 06115 return -1; 06116 } 06117 memcpy(®->us, &us, sizeof(reg->us)); 06118 if (ies->msgcount >= 0) 06119 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 06120 /* always refresh the registration at the interval requested by the server 06121 we are registering to 06122 */ 06123 reg->refresh = refresh; 06124 AST_SCHED_DEL(sched, reg->expire); 06125 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 06126 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 06127 if (option_verbose > 2) { 06128 if (reg->messages > 255) 06129 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 06130 else if (reg->messages > 1) 06131 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages); 06132 else if (reg->messages > 0) 06133 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n"); 06134 else 06135 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n"); 06136 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 06137 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 06138 } 06139 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 06140 } 06141 reg->regstate = REG_STATE_REGISTERED; 06142 return 0; 06143 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3822 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.
03823 { 03824 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03825 if (option_debug) 03826 ast_log(LOG_DEBUG, "Answering IAX2 call\n"); 03827 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 03828 }
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 3667 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.
03668 { 03669 struct ast_channel *cs[3]; 03670 struct ast_channel *who, *other; 03671 int to = -1; 03672 int res = -1; 03673 int transferstarted=0; 03674 struct ast_frame *f; 03675 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 03676 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 03677 struct timeval waittimer = {0, 0}, tv; 03678 03679 lock_both(callno0, callno1); 03680 if (!iaxs[callno0] || !iaxs[callno1]) { 03681 unlock_both(callno0, callno1); 03682 return AST_BRIDGE_FAILED; 03683 } 03684 /* Put them in native bridge mode */ 03685 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) { 03686 iaxs[callno0]->bridgecallno = callno1; 03687 iaxs[callno1]->bridgecallno = callno0; 03688 } 03689 /* If the bridge got retried, don't queue up more packets - the transfer request will be retransmitted as necessary */ 03690 if (iaxs[callno0]->transferring && iaxs[callno1]->transferring) { 03691 transferstarted = 1; 03692 } 03693 unlock_both(callno0, callno1); 03694 03695 /* If not, try to bridge until we can execute a transfer, if we can */ 03696 cs[0] = c0; 03697 cs[1] = c1; 03698 for (/* ever */;;) { 03699 /* Check in case we got masqueraded into */ 03700 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 03701 if (option_verbose > 2) 03702 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n"); 03703 /* Remove from native mode */ 03704 if (c0->tech == &iax2_tech) { 03705 ast_mutex_lock(&iaxsl[callno0]); 03706 iaxs[callno0]->bridgecallno = 0; 03707 ast_mutex_unlock(&iaxsl[callno0]); 03708 } 03709 if (c1->tech == &iax2_tech) { 03710 ast_mutex_lock(&iaxsl[callno1]); 03711 iaxs[callno1]->bridgecallno = 0; 03712 ast_mutex_unlock(&iaxsl[callno1]); 03713 } 03714 return AST_BRIDGE_FAILED_NOWARN; 03715 } 03716 if (c0->nativeformats != c1->nativeformats) { 03717 if (option_verbose > 2) { 03718 char buf0[255]; 03719 char buf1[255]; 03720 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 03721 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 03722 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 03723 } 03724 /* Remove from native mode */ 03725 lock_both(callno0, callno1); 03726 if (iaxs[callno0]) 03727 iaxs[callno0]->bridgecallno = 0; 03728 if (iaxs[callno1]) 03729 iaxs[callno1]->bridgecallno = 0; 03730 unlock_both(callno0, callno1); 03731 return AST_BRIDGE_FAILED_NOWARN; 03732 } 03733 /* check if transfered and if we really want native bridging */ 03734 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) { 03735 /* Try the transfer */ 03736 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 03737 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA))) 03738 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 03739 transferstarted = 1; 03740 } 03741 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 03742 /* Call has been transferred. We're no longer involved */ 03743 gettimeofday(&tv, NULL); 03744 if (ast_tvzero(waittimer)) { 03745 waittimer = tv; 03746 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 03747 c0->_softhangup |= AST_SOFTHANGUP_DEV; 03748 c1->_softhangup |= AST_SOFTHANGUP_DEV; 03749 *fo = NULL; 03750 *rc = c0; 03751 res = AST_BRIDGE_COMPLETE; 03752 break; 03753 } 03754 } 03755 to = 1000; 03756 who = ast_waitfor_n(cs, 2, &to); 03757 if (timeoutms > -1) { 03758 timeoutms -= (1000 - to); 03759 if (timeoutms < 0) 03760 timeoutms = 0; 03761 } 03762 if (!who) { 03763 if (!timeoutms) { 03764 res = AST_BRIDGE_RETRY; 03765 break; 03766 } 03767 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 03768 res = AST_BRIDGE_FAILED; 03769 break; 03770 } 03771 continue; 03772 } 03773 f = ast_read(who); 03774 if (!f) { 03775 *fo = NULL; 03776 *rc = who; 03777 res = AST_BRIDGE_COMPLETE; 03778 break; 03779 } 03780 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) { 03781 *fo = f; 03782 *rc = who; 03783 res = AST_BRIDGE_COMPLETE; 03784 break; 03785 } 03786 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 03787 if ((f->frametype == AST_FRAME_VOICE) || 03788 (f->frametype == AST_FRAME_TEXT) || 03789 (f->frametype == AST_FRAME_VIDEO) || 03790 (f->frametype == AST_FRAME_IMAGE) || 03791 (f->frametype == AST_FRAME_DTMF) || 03792 (f->frametype == AST_FRAME_CONTROL)) { 03793 /* monitored dtmf take out of the bridge. 03794 * check if we monitor the specific source. 03795 */ 03796 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 03797 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 03798 *rc = who; 03799 *fo = f; 03800 res = AST_BRIDGE_COMPLETE; 03801 /* Remove from native mode */ 03802 break; 03803 } 03804 /* everything else goes to the other side */ 03805 ast_write(other, f); 03806 } 03807 ast_frfree(f); 03808 /* Swap who gets priority */ 03809 cs[2] = cs[0]; 03810 cs[0] = cs[1]; 03811 cs[1] = cs[2]; 03812 } 03813 lock_both(callno0, callno1); 03814 if(iaxs[callno0]) 03815 iaxs[callno0]->bridgecallno = 0; 03816 if(iaxs[callno1]) 03817 iaxs[callno1]->bridgecallno = 0; 03818 unlock_both(callno0, callno1); 03819 return res; 03820 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 3364 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.
03365 { 03366 struct sockaddr_in sin; 03367 char *l=NULL, *n=NULL, *tmpstr; 03368 struct iax_ie_data ied; 03369 char *defaultrdest = "s"; 03370 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03371 struct parsed_dial_string pds; 03372 struct create_addr_info cai; 03373 03374 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 03375 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 03376 return -1; 03377 } 03378 03379 memset(&cai, 0, sizeof(cai)); 03380 cai.encmethods = iax2_encryption; 03381 03382 memset(&pds, 0, sizeof(pds)); 03383 tmpstr = ast_strdupa(dest); 03384 parse_dial_string(tmpstr, &pds); 03385 03386 if (ast_strlen_zero(pds.peer)) { 03387 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 03388 return -1; 03389 } 03390 03391 if (!pds.exten) { 03392 pds.exten = defaultrdest; 03393 } 03394 03395 if (create_addr(pds.peer, c, &sin, &cai)) { 03396 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 03397 return -1; 03398 } 03399 03400 if (!pds.username && !ast_strlen_zero(cai.username)) 03401 pds.username = cai.username; 03402 if (!pds.password && !ast_strlen_zero(cai.secret)) 03403 pds.password = cai.secret; 03404 if (!pds.key && !ast_strlen_zero(cai.outkey)) 03405 pds.key = cai.outkey; 03406 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 03407 pds.context = cai.peercontext; 03408 03409 /* Keep track of the context for outgoing calls too */ 03410 ast_copy_string(c->context, cai.context, sizeof(c->context)); 03411 03412 if (pds.port) 03413 sin.sin_port = htons(atoi(pds.port)); 03414 03415 l = c->cid.cid_num; 03416 n = c->cid.cid_name; 03417 03418 /* Now build request */ 03419 memset(&ied, 0, sizeof(ied)); 03420 03421 /* On new call, first IE MUST be IAX version of caller */ 03422 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 03423 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 03424 if (pds.options && strchr(pds.options, 'a')) { 03425 /* Request auto answer */ 03426 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 03427 } 03428 03429 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 03430 03431 if (l) { 03432 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 03433 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03434 } else { 03435 if (n) 03436 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03437 else 03438 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 03439 } 03440 03441 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton); 03442 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns); 03443 03444 if (n) 03445 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 03446 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani) 03447 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani); 03448 03449 if (!ast_strlen_zero(c->language)) 03450 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 03451 if (!ast_strlen_zero(c->cid.cid_dnid)) 03452 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid); 03453 if (!ast_strlen_zero(c->cid.cid_rdnis)) 03454 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis); 03455 03456 if (pds.context) 03457 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 03458 03459 if (pds.username) 03460 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 03461 03462 if (cai.encmethods) 03463 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 03464 03465 ast_mutex_lock(&iaxsl[callno]); 03466 03467 if (!ast_strlen_zero(c->context)) 03468 ast_string_field_set(iaxs[callno], context, c->context); 03469 03470 if (pds.username) 03471 ast_string_field_set(iaxs[callno], username, pds.username); 03472 03473 iaxs[callno]->encmethods = cai.encmethods; 03474 03475 iaxs[callno]->adsi = cai.adsi; 03476 03477 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 03478 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 03479 03480 if (pds.key) 03481 ast_string_field_set(iaxs[callno], outkey, pds.key); 03482 if (pds.password) 03483 ast_string_field_set(iaxs[callno], secret, pds.password); 03484 03485 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); 03486 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); 03487 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 03488 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 03489 03490 if (iaxs[callno]->maxtime) { 03491 /* Initialize pingtime and auto-congest time */ 03492 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 03493 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 03494 } else if (autokill) { 03495 iaxs[callno]->pingtime = autokill / 2; 03496 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 03497 } 03498 03499 /* send the command using the appropriate socket for this peer */ 03500 iaxs[callno]->sockfd = cai.sockfd; 03501 03502 /* Transmit the string in a "NEW" request */ 03503 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 03504 03505 ast_mutex_unlock(&iaxsl[callno]); 03506 ast_setstate(c, AST_STATE_RINGING); 03507 03508 return 0; 03509 }
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 10717 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.
10718 { 10719 int res = 0; 10720 struct iax2_dpcache *dp; 10721 #if 0 10722 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10723 #endif 10724 if ((priority != 1) && (priority != 2)) 10725 return 0; 10726 ast_mutex_lock(&dpcache_lock); 10727 dp = find_cache(chan, data, context, exten, priority); 10728 if (dp) { 10729 if (dp->flags & CACHE_FLAG_CANEXIST) 10730 res= 1; 10731 } 10732 ast_mutex_unlock(&dpcache_lock); 10733 if (!dp) { 10734 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10735 } 10736 return res; 10737 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 3267 of file chan_iax2.c.
References ast_localtime(), ast_strlen_zero(), and t.
Referenced by iax2_call(), and update_registry().
03268 { 03269 time_t t; 03270 struct tm tm; 03271 unsigned int tmp; 03272 time(&t); 03273 if (!ast_strlen_zero(tz)) 03274 ast_localtime(&t, &tm, tz); 03275 else 03276 ast_localtime(&t, &tm, NULL); 03277 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 03278 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 03279 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 03280 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 03281 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 03282 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 03283 return tmp; 03284 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 1329 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(), remove_by_transfercallno(), sched, chan_iax2_pvt::transfercallno, 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().
01330 { 01331 struct chan_iax2_pvt *pvt; 01332 struct ast_channel *owner; 01333 01334 retry: 01335 pvt = iaxs[callno]; 01336 gettimeofday(&lastused[callno], NULL); 01337 01338 owner = pvt ? pvt->owner : NULL; 01339 01340 if (owner) { 01341 if (ast_mutex_trylock(&owner->lock)) { 01342 if (option_debug > 2) 01343 ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n"); 01344 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01345 goto retry; 01346 } 01347 } 01348 if (!owner && iaxs[callno]) { 01349 AST_SCHED_DEL_SPINLOCK(sched, iaxs[callno]->lagid, &iaxsl[callno]); 01350 AST_SCHED_DEL_SPINLOCK(sched, iaxs[callno]->pingid, &iaxsl[callno]); 01351 iaxs[callno] = NULL; 01352 } 01353 01354 if (pvt) { 01355 if (!owner) { 01356 pvt->owner = NULL; 01357 } else { 01358 /* If there's an owner, prod it to give up */ 01359 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 01360 * because we already hold the owner channel lock. */ 01361 ast_queue_hangup(owner); 01362 } 01363 01364 if (pvt->peercallno) { 01365 remove_by_peercallno(pvt); 01366 } 01367 01368 if (pvt->transfercallno) { 01369 remove_by_transfercallno(pvt); 01370 } 01371 01372 if (!owner) { 01373 ao2_ref(pvt, -1); 01374 pvt = NULL; 01375 } 01376 } 01377 01378 if (owner) { 01379 ast_mutex_unlock(&owner->lock); 01380 } 01381 01382 if (callno & 0x4000) { 01383 update_max_trunk(); 01384 } 01385 }
static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1240 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().
01241 { 01242 /* Decrement AUTHREQ count if needed */ 01243 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01244 struct iax2_user *user; 01245 struct iax2_user tmp_user = { 01246 .name = pvt->username, 01247 }; 01248 01249 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01250 if (user) { 01251 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01252 user = user_unref(user); 01253 } 01254 01255 ast_clear_flag(pvt, IAX_MAXAUTHREQ); 01256 } 01257 01258 /* No more pings or lagrq's */ 01259 AST_SCHED_DEL(sched, pvt->pingid); 01260 AST_SCHED_DEL(sched, pvt->lagid); 01261 AST_SCHED_DEL(sched, pvt->autoid); 01262 AST_SCHED_DEL(sched, pvt->authid); 01263 AST_SCHED_DEL(sched, pvt->initid); 01264 AST_SCHED_DEL(sched, pvt->jbid); 01265 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 10908 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().
10909 { 10910 struct parsed_dial_string pds; 10911 char *tmp = ast_strdupa(data); 10912 struct iax2_peer *p; 10913 int res = AST_DEVICE_INVALID; 10914 10915 memset(&pds, 0, sizeof(pds)); 10916 parse_dial_string(tmp, &pds); 10917 10918 if (ast_strlen_zero(pds.peer)) { 10919 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 10920 return res; 10921 } 10922 10923 if (option_debug > 2) 10924 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer); 10925 10926 /* SLD: FIXME: second call to find_peer during registration */ 10927 if (!(p = find_peer(pds.peer, 1))) 10928 return res; 10929 10930 res = AST_DEVICE_UNAVAILABLE; 10931 if (option_debug > 2) 10932 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 10933 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 10934 10935 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 10936 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 10937 /* Peer is registered, or have default IP address 10938 and a valid registration */ 10939 if (p->historicms == 0 || p->historicms <= p->maxms) 10940 /* let the core figure out whether it is in use or not */ 10941 res = AST_DEVICE_UNKNOWN; 10942 } 10943 10944 peer_unref(p); 10945 10946 return res; 10947 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 2883 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02884 { 02885 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 02886 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 2888 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02889 { 02890 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 02891 }
static int iax2_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5122 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05123 { 05124 if (argc < 2 || argc > 3) 05125 return RESULT_SHOWUSAGE; 05126 iaxdebug = 1; 05127 ast_cli(fd, "IAX2 Debugging Enabled\n"); 05128 return RESULT_SUCCESS; 05129 }
static int iax2_do_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5140 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05141 { 05142 if (argc < 3 || argc > 4) 05143 return RESULT_SHOWUSAGE; 05144 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 05145 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 05146 return RESULT_SUCCESS; 05147 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 8867 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().
08868 { 08869 struct iax_ie_data ied; 08870 if (option_debug && iaxdebug) 08871 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username); 08872 08873 if (reg->dnsmgr && 08874 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) { 08875 /* Maybe the IP has changed, force DNS refresh */ 08876 ast_dnsmgr_refresh(reg->dnsmgr); 08877 } 08878 08879 /* 08880 * if IP has Changed, free allocated call to create a new one with new IP 08881 * call has the pointer to IP and must be updated to the new one 08882 */ 08883 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 08884 int callno = reg->callno; 08885 ast_mutex_lock(&iaxsl[callno]); 08886 iax2_destroy(callno); 08887 ast_mutex_unlock(&iaxsl[callno]); 08888 reg->callno = 0; 08889 } 08890 if (!reg->addr.sin_addr.s_addr) { 08891 if (option_debug && iaxdebug) 08892 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username); 08893 /* Setup the next registration attempt */ 08894 AST_SCHED_DEL(sched, reg->expire); 08895 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08896 return -1; 08897 } 08898 08899 if (!reg->callno) { 08900 if (option_debug) 08901 ast_log(LOG_DEBUG, "Allocate call number\n"); 08902 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0); 08903 if (reg->callno < 1) { 08904 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 08905 return -1; 08906 } else if (option_debug) 08907 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno); 08908 iaxs[reg->callno]->reg = reg; 08909 ast_mutex_unlock(&iaxsl[reg->callno]); 08910 } 08911 /* Schedule the next registration attempt */ 08912 AST_SCHED_DEL(sched, reg->expire); 08913 /* Setup the next registration a little early */ 08914 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08915 /* Send the request */ 08916 memset(&ied, 0, sizeof(ied)); 08917 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 08918 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 08919 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 08920 reg->regstate = REG_STATE_REGSENT; 08921 return 0; 08922 }
static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 5926 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
05927 { 05928 #ifdef SCHED_MULTITHREADED 05929 if (schedule_action(__iax2_do_register_s, data)) 05930 #endif 05931 __iax2_do_register_s(data); 05932 return 0; 05933 }
static int iax2_do_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5131 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05132 { 05133 if (argc < 3 || argc > 4) 05134 return RESULT_SHOWUSAGE; 05135 iaxtrunkdebug = 1; 05136 ast_cli(fd, "IAX2 Trunk Debug Requested\n"); 05137 return RESULT_SUCCESS; 05138 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 6629 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().
06630 { 06631 struct iax_ie_data ied; 06632 /* Auto-hangup with 30 seconds of inactivity */ 06633 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 06634 iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno); 06635 memset(&ied, 0, sizeof(ied)); 06636 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 06637 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 06638 dp->flags |= CACHE_FLAG_TRANSMITTED; 06639 }
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 10763 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.
10764 { 10765 char odata[256]; 10766 char req[256]; 10767 char *ncontext; 10768 struct iax2_dpcache *dp; 10769 struct ast_app *dial; 10770 #if 0 10771 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); 10772 #endif 10773 if (priority == 2) { 10774 /* Indicate status, can be overridden in dialplan */ 10775 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 10776 if (dialstatus) { 10777 dial = pbx_findapp(dialstatus); 10778 if (dial) 10779 pbx_exec(chan, dial, ""); 10780 } 10781 return -1; 10782 } else if (priority != 1) 10783 return -1; 10784 ast_mutex_lock(&dpcache_lock); 10785 dp = find_cache(chan, data, context, exten, priority); 10786 if (dp) { 10787 if (dp->flags & CACHE_FLAG_EXISTS) { 10788 ast_copy_string(odata, data, sizeof(odata)); 10789 ncontext = strchr(odata, '/'); 10790 if (ncontext) { 10791 *ncontext = '\0'; 10792 ncontext++; 10793 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 10794 } else { 10795 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 10796 } 10797 if (option_verbose > 2) 10798 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req); 10799 } else { 10800 ast_mutex_unlock(&dpcache_lock); 10801 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 10802 return -1; 10803 } 10804 } 10805 ast_mutex_unlock(&dpcache_lock); 10806 dial = pbx_findapp("Dial"); 10807 if (dial) { 10808 return pbx_exec(chan, dial, req); 10809 } else { 10810 ast_log(LOG_WARNING, "No dial application registered\n"); 10811 } 10812 return -1; 10813 }
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 10694 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.
10695 { 10696 struct iax2_dpcache *dp; 10697 int res = 0; 10698 #if 0 10699 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10700 #endif 10701 if ((priority != 1) && (priority != 2)) 10702 return 0; 10703 ast_mutex_lock(&dpcache_lock); 10704 dp = find_cache(chan, data, context, exten, priority); 10705 if (dp) { 10706 if (dp->flags & CACHE_FLAG_EXISTS) 10707 res= 1; 10708 } 10709 ast_mutex_unlock(&dpcache_lock); 10710 if (!dp) { 10711 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10712 } 10713 return res; 10714 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 2910 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.
02911 { 02912 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 02913 ast_mutex_lock(&iaxsl[callno]); 02914 if (iaxs[callno]) 02915 iaxs[callno]->owner = newchan; 02916 else 02917 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 02918 ast_mutex_unlock(&iaxsl[callno]); 02919 return 0; 02920 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1323 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().
01324 { 01325 AST_SCHED_DEL(sched, fr->retrans); 01326 iax_frame_free(fr); 01327 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len | |||
) | [static] |
Definition at line 1210 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().
01211 { 01212 struct iax2_peer *peer = NULL; 01213 int res = 0; 01214 struct ao2_iterator i; 01215 01216 i = ao2_iterator_init(peers, 0); 01217 while ((peer = ao2_iterator_next(&i))) { 01218 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01219 (peer->addr.sin_port == sin.sin_port)) { 01220 ast_copy_string(host, peer->name, len); 01221 peer_unref(peer); 01222 res = 1; 01223 break; 01224 } 01225 peer_unref(peer); 01226 } 01227 01228 if (!peer) { 01229 peer = realtime_peer(NULL, &sin); 01230 if (peer) { 01231 ast_copy_string(host, peer->name, len); 01232 peer_unref(peer); 01233 res = 1; 01234 } 01235 } 01236 01237 return res; 01238 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 3889 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().
03890 { 03891 struct iax2_peer *peer; 03892 int res = 0; 03893 struct ao2_iterator i; 03894 03895 i = ao2_iterator_init(peers, 0); 03896 while ((peer = ao2_iterator_next(&i))) { 03897 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 03898 (peer->addr.sin_port == sin.sin_port)) { 03899 res = ast_test_flag(peer, IAX_TRUNK); 03900 peer_unref(peer); 03901 break; 03902 } 03903 peer_unref(peer); 03904 } 03905 03906 return res; 03907 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3511 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_verbose(), CALLNO_TO_PTR, ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), iax2_sched_add(), 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.
03512 { 03513 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03514 struct iax_ie_data ied; 03515 int alreadygone; 03516 memset(&ied, 0, sizeof(ied)); 03517 ast_mutex_lock(&iaxsl[callno]); 03518 if (callno && iaxs[callno]) { 03519 if (option_debug) 03520 ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name); 03521 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 03522 /* Send the hangup unless we have had a transmission error or are already gone */ 03523 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 03524 if (!iaxs[callno]->error && !alreadygone) { 03525 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) { 03526 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno); 03527 } 03528 if (!iaxs[callno]) { 03529 ast_mutex_unlock(&iaxsl[callno]); 03530 return 0; 03531 } 03532 } 03533 /* Explicitly predestroy it */ 03534 iax2_predestroy(callno); 03535 /* If we were already gone to begin with, destroy us now */ 03536 if (iaxs[callno] && alreadygone) { 03537 if (option_debug) 03538 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name); 03539 iax2_destroy(callno); 03540 } else if (iaxs[callno]) { 03541 iax2_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)); 03542 } 03543 } else if (c->tech_pvt) { 03544 /* If this call no longer exists, but the channel still 03545 * references it we need to set the channel's tech_pvt to null 03546 * to avoid ast_channel_free() trying to free it. 03547 */ 03548 c->tech_pvt = NULL; 03549 } 03550 ast_mutex_unlock(&iaxsl[callno]); 03551 if (option_verbose > 2) 03552 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name); 03553 return 0; 03554 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 3830 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().
03831 { 03832 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03833 struct chan_iax2_pvt *pvt; 03834 int res = 0; 03835 03836 if (option_debug && iaxdebug) 03837 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition); 03838 03839 ast_mutex_lock(&iaxsl[callno]); 03840 pvt = iaxs[callno]; 03841 03842 if (wait_for_peercallno(pvt)) { 03843 res = -1; 03844 goto done; 03845 } 03846 03847 switch (condition) { 03848 case AST_CONTROL_HOLD: 03849 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03850 ast_moh_start(c, data, pvt->mohinterpret); 03851 goto done; 03852 } 03853 break; 03854 case AST_CONTROL_UNHOLD: 03855 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03856 ast_moh_stop(c); 03857 goto done; 03858 } 03859 } 03860 03861 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 03862 03863 done: 03864 ast_mutex_unlock(&iaxsl[callno]); 03865 03866 return res; 03867 }
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 10740 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.
10741 { 10742 int res = 0; 10743 struct iax2_dpcache *dp; 10744 #if 0 10745 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10746 #endif 10747 if ((priority != 1) && (priority != 2)) 10748 return 0; 10749 ast_mutex_lock(&dpcache_lock); 10750 dp = find_cache(chan, data, context, exten, priority); 10751 if (dp) { 10752 if (dp->flags & CACHE_FLAG_MATCHMORE) 10753 res= 1; 10754 } 10755 ast_mutex_unlock(&dpcache_lock); 10756 if (!dp) { 10757 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10758 } 10759 return res; 10760 }
static int iax2_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5149 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05150 { 05151 if (argc < 3 || argc > 4) 05152 return RESULT_SHOWUSAGE; 05153 iaxdebug = 0; 05154 ast_cli(fd, "IAX2 Debugging Disabled\n"); 05155 return RESULT_SUCCESS; 05156 }
static int iax2_no_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5167 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05168 { 05169 if (argc < 4 || argc > 5) 05170 return RESULT_SHOWUSAGE; 05171 jb_setoutput(jb_error_output, jb_warning_output, NULL); 05172 jb_debug_output("\n"); 05173 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 05174 return RESULT_SUCCESS; 05175 }
static int iax2_no_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5158 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05159 { 05160 if (argc < 4 || argc > 5) 05161 return RESULT_SHOWUSAGE; 05162 iaxtrunkdebug = 0; 05163 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n"); 05164 return RESULT_SUCCESS; 05165 }
static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 9066 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
09067 { 09068 struct iax2_peer *peer = (struct iax2_peer *)data; 09069 peer->pokeexpire = -1; 09070 #ifdef SCHED_MULTITHREADED 09071 if (schedule_action(__iax2_poke_noanswer, data)) 09072 #endif 09073 __iax2_poke_noanswer(data); 09074 peer_unref(peer); 09075 return 0; 09076 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 9087 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().
09088 { 09089 int callno; 09090 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) { 09091 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 09092 immediately after clearing things out */ 09093 peer->lastms = 0; 09094 peer->historicms = 0; 09095 peer->pokeexpire = -1; 09096 peer->callno = 0; 09097 return 0; 09098 } 09099 09100 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 09101 if ((callno = peer->callno) > 0) { 09102 ast_log(LOG_NOTICE, "Still have a callno...\n"); 09103 ast_mutex_lock(&iaxsl[callno]); 09104 iax2_destroy(callno); 09105 ast_mutex_unlock(&iaxsl[callno]); 09106 } 09107 if (heldcall) 09108 ast_mutex_unlock(&iaxsl[heldcall]); 09109 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0); 09110 if (heldcall) 09111 ast_mutex_lock(&iaxsl[heldcall]); 09112 if (peer->callno < 1) { 09113 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 09114 return -1; 09115 } 09116 09117 /* Speed up retransmission times for this qualify call */ 09118 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 09119 iaxs[peer->callno]->peerpoke = peer; 09120 09121 /* Remove any pending pokeexpire task */ 09122 if (peer->pokeexpire > -1) { 09123 if (!ast_sched_del(sched, peer->pokeexpire)) { 09124 peer->pokeexpire = -1; 09125 peer_unref(peer); 09126 } 09127 } 09128 09129 /* Queue up a new task to handle no reply */ 09130 /* If the host is already unreachable then use the unreachable interval instead */ 09131 if (peer->lastms < 0) { 09132 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 09133 } else 09134 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 09135 09136 if (peer->pokeexpire == -1) 09137 peer_unref(peer); 09138 09139 /* And send the poke */ 09140 ast_mutex_lock(&iaxsl[callno]); 09141 if (iaxs[callno]) { 09142 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1); 09143 } 09144 ast_mutex_unlock(&iaxsl[callno]); 09145 09146 return 0; 09147 }
static int iax2_poke_peer_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9078 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
09079 { 09080 struct iax2_peer *peer = obj; 09081 09082 iax2_poke_peer(peer, 0); 09083 09084 return 0; 09085 }
static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 6669 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
06670 { 06671 struct iax2_peer *peer = (struct iax2_peer *)data; 06672 peer->pokeexpire = -1; 06673 #ifdef SCHED_MULTITHREADED 06674 if (schedule_action(__iax2_poke_peer_s, data)) 06675 #endif 06676 __iax2_poke_peer_s(data); 06677 return 0; 06678 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 2232 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().
02233 { 02234 struct ast_channel *c; 02235 struct chan_iax2_pvt *pvt = iaxs[callno]; 02236 02237 if (!pvt) 02238 return -1; 02239 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 02240 iax2_destroy_helper(pvt); 02241 ast_set_flag(pvt, IAX_ALREADYGONE); 02242 } 02243 c = pvt->owner; 02244 if (c) { 02245 c->tech_pvt = NULL; 02246 iax2_queue_hangup(callno); 02247 pvt->owner = NULL; 02248 ast_module_unref(ast_module_info->self); 02249 } 02250 return 0; 02251 }
static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 8742 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().
08743 { 08744 struct iax2_thread *thread = data; 08745 struct timeval tv; 08746 struct timespec ts; 08747 int put_into_idle = 0; 08748 08749 ast_atomic_fetchadd_int(&iaxactivethreadcount,1); 08750 pthread_cleanup_push(iax2_process_thread_cleanup, data); 08751 for(;;) { 08752 /* Wait for something to signal us to be awake */ 08753 ast_mutex_lock(&thread->lock); 08754 08755 /* Flag that we're ready to accept signals */ 08756 thread->ready_for_signal = 1; 08757 08758 /* Put into idle list if applicable */ 08759 if (put_into_idle) 08760 insert_idle_thread(thread); 08761 08762 if (thread->type == IAX_TYPE_DYNAMIC) { 08763 struct iax2_thread *t = NULL; 08764 /* Wait to be signalled or time out */ 08765 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08766 ts.tv_sec = tv.tv_sec; 08767 ts.tv_nsec = tv.tv_usec * 1000; 08768 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 08769 /* This thread was never put back into the available dynamic 08770 * thread list, so just go away. */ 08771 if (!put_into_idle) { 08772 ast_mutex_unlock(&thread->lock); 08773 break; 08774 } 08775 AST_LIST_LOCK(&dynamic_list); 08776 /* Account for the case where this thread is acquired *right* after a timeout */ 08777 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 08778 iaxdynamicthreadcount--; 08779 AST_LIST_UNLOCK(&dynamic_list); 08780 if (t) { 08781 /* This dynamic thread timed out waiting for a task and was 08782 * not acquired immediately after the timeout, 08783 * so it's time to go away. */ 08784 ast_mutex_unlock(&thread->lock); 08785 break; 08786 } 08787 /* Someone grabbed our thread *right* after we timed out. 08788 * Wait for them to set us up with something to do and signal 08789 * us to continue. */ 08790 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08791 ts.tv_sec = tv.tv_sec; 08792 ts.tv_nsec = tv.tv_usec * 1000; 08793 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) 08794 { 08795 ast_mutex_unlock(&thread->lock); 08796 break; 08797 } 08798 } 08799 } else { 08800 ast_cond_wait(&thread->cond, &thread->lock); 08801 } 08802 08803 /* Go back into our respective list */ 08804 put_into_idle = 1; 08805 08806 ast_mutex_unlock(&thread->lock); 08807 08808 if (thread->iostate == IAX_IOSTATE_IDLE) 08809 continue; 08810 08811 /* Add ourselves to the active list now */ 08812 AST_LIST_LOCK(&active_list); 08813 AST_LIST_INSERT_HEAD(&active_list, thread, list); 08814 AST_LIST_UNLOCK(&active_list); 08815 08816 /* See what we need to do */ 08817 switch(thread->iostate) { 08818 case IAX_IOSTATE_READY: 08819 thread->actions++; 08820 thread->iostate = IAX_IOSTATE_PROCESSING; 08821 socket_process(thread); 08822 handle_deferred_full_frames(thread); 08823 break; 08824 case IAX_IOSTATE_SCHEDREADY: 08825 thread->actions++; 08826 thread->iostate = IAX_IOSTATE_PROCESSING; 08827 #ifdef SCHED_MULTITHREADED 08828 thread->schedfunc(thread->scheddata); 08829 #endif 08830 break; 08831 } 08832 time(&thread->checktime); 08833 thread->iostate = IAX_IOSTATE_IDLE; 08834 #ifdef DEBUG_SCHED_MULTITHREAD 08835 thread->curfunc[0]='\0'; 08836 #endif 08837 08838 /* Now... remove ourselves from the active list, and return to the idle list */ 08839 AST_LIST_LOCK(&active_list); 08840 AST_LIST_REMOVE(&active_list, thread, list); 08841 AST_LIST_UNLOCK(&active_list); 08842 08843 /* Make sure another frame didn't sneak in there after we thought we were done. */ 08844 handle_deferred_full_frames(thread); 08845 } 08846 08847 /*!\note For some reason, idle threads are exiting without being removed 08848 * from an idle list, which is causing memory corruption. Forcibly remove 08849 * it from the list, if it's there. 08850 */ 08851 AST_LIST_LOCK(&idle_list); 08852 AST_LIST_REMOVE(&idle_list, thread, list); 08853 AST_LIST_UNLOCK(&idle_list); 08854 08855 AST_LIST_LOCK(&dynamic_list); 08856 AST_LIST_REMOVE(&dynamic_list, thread, list); 08857 AST_LIST_UNLOCK(&dynamic_list); 08858 08859 /* I am exiting here on my own volition, I need to clean up my own data structures 08860 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 08861 */ 08862 pthread_cleanup_pop(1); 08863 08864 return NULL; 08865 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 8733 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().
08734 { 08735 struct iax2_thread *thread = data; 08736 ast_mutex_destroy(&thread->lock); 08737 ast_cond_destroy(&thread->cond); 08738 free(thread); 08739 ast_atomic_dec_and_test(&iaxactivethreadcount); 08740 }
static int iax2_prov_cmd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 9021 of file chan_iax2.c.
References ast_cli(), iax2_provision(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
09022 { 09023 int force = 0; 09024 int res; 09025 if (argc < 4) 09026 return RESULT_SHOWUSAGE; 09027 if ((argc > 4)) { 09028 if (!strcasecmp(argv[4], "forced")) 09029 force = 1; 09030 else 09031 return RESULT_SHOWUSAGE; 09032 } 09033 res = iax2_provision(NULL, -1, argv[2], argv[3], force); 09034 if (res < 0) 09035 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]); 09036 else if (res < 1) 09037 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]); 09038 else 09039 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : ""); 09040 return RESULT_SUCCESS; 09041 }
static char* iax2_prov_complete_template_3rd | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 8924 of file chan_iax2.c.
References iax_prov_complete_template().
08925 { 08926 if (pos != 3) 08927 return NULL; 08928 return iax_prov_complete_template(line, word, pos, state); 08929 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 8931 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().
08932 { 08933 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 08934 is found for template */ 08935 struct iax_ie_data provdata; 08936 struct iax_ie_data ied; 08937 unsigned int sig; 08938 struct sockaddr_in sin; 08939 int callno; 08940 struct create_addr_info cai; 08941 08942 memset(&cai, 0, sizeof(cai)); 08943 08944 if (option_debug) 08945 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template); 08946 08947 if (iax_provision_build(&provdata, &sig, template, force)) { 08948 if (option_debug) 08949 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template); 08950 return 0; 08951 } 08952 08953 if (end) { 08954 memcpy(&sin, end, sizeof(sin)); 08955 cai.sockfd = sockfd; 08956 } else if (create_addr(dest, NULL, &sin, &cai)) 08957 return -1; 08958 08959 /* Build the rest of the message */ 08960 memset(&ied, 0, sizeof(ied)); 08961 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 08962 08963 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 08964 if (!callno) 08965 return -1; 08966 08967 if (iaxs[callno]) { 08968 /* Schedule autodestruct in case they don't ever give us anything back */ 08969 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 08970 iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno); 08971 ast_set_flag(iaxs[callno], IAX_PROVISION); 08972 /* Got a call number now, so go ahead and send the provisioning information */ 08973 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 08974 } 08975 ast_mutex_unlock(&iaxsl[callno]); 08976 08977 return 1; 08978 }
static int iax2_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2356 of file chan_iax2.c.
References ao2_unlink(), ast_cli(), ast_set_flag, ast_test_flag, expire_registry(), find_peer(), find_user(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, peer_ref(), peer_unref(), prune_peers(), prune_users(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and user_unref().
02357 { 02358 struct iax2_peer *peer = NULL; 02359 struct iax2_user *user = NULL; 02360 02361 if (argc != 4) 02362 return RESULT_SHOWUSAGE; 02363 if (!strcmp(argv[3],"all")) { 02364 prune_users(); 02365 prune_peers(); 02366 ast_cli(fd, "OK cache is flushed.\n"); 02367 return RESULT_SUCCESS; 02368 } 02369 peer = find_peer(argv[3], 0); 02370 user = find_user(argv[3]); 02371 if (peer || user) { 02372 if (peer) { 02373 if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 02374 ast_set_flag(peer, IAX_RTAUTOCLEAR); 02375 expire_registry(peer_ref(peer)); 02376 ast_cli(fd, "Peer %s was removed from the cache.\n", argv[3]); 02377 } else { 02378 ast_cli(fd, "Peer %s is not eligible for this operation.\n", argv[3]); 02379 } 02380 peer_unref(peer); 02381 } 02382 if (user) { 02383 if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) { 02384 ast_set_flag(user, IAX_RTAUTOCLEAR); 02385 ast_cli(fd, "User %s was removed from the cache.\n", argv[3]); 02386 } else { 02387 ast_cli(fd, "User %s is not eligible for this operation.\n", argv[3]); 02388 } 02389 ao2_unlink(users,user); 02390 user_unref(user); 02391 } 02392 } else { 02393 ast_cli(fd, "%s was not found in the cache.\n", argv[3]); 02394 } 02395 02396 return RESULT_SUCCESS; 02397 }
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 1842 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().
01844 { 01845 for (;;) { 01846 if (iaxs[callno] && iaxs[callno]->owner) { 01847 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01848 /* Avoid deadlock by pausing and trying again */ 01849 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01850 } else { 01851 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 01852 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01853 break; 01854 } 01855 } else 01856 break; 01857 } 01858 return 0; 01859 }
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 1780 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().
01781 { 01782 for (;;) { 01783 if (iaxs[callno] && iaxs[callno]->owner) { 01784 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01785 /* Avoid deadlock by pausing and trying again */ 01786 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01787 } else { 01788 ast_queue_frame(iaxs[callno]->owner, f); 01789 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01790 break; 01791 } 01792 } else 01793 break; 01794 } 01795 return 0; 01796 }
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 1811 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().
01812 { 01813 for (;;) { 01814 if (iaxs[callno] && iaxs[callno]->owner) { 01815 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01816 /* Avoid deadlock by pausing and trying again */ 01817 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01818 } else { 01819 ast_queue_hangup(iaxs[callno]->owner); 01820 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01821 break; 01822 } 01823 } else 01824 break; 01825 } 01826 return 0; 01827 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3620 of file chan_iax2.c.
References ast_log(), and LOG_NOTICE.
03621 { 03622 ast_log(LOG_NOTICE, "I should never be called! Hanging up.\n"); 03623 return NULL; 03624 }
static int iax2_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 6145 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().
06146 { 06147 struct iax2_registry *reg; 06148 char copy[256]; 06149 char *username, *hostname, *secret; 06150 char *porta; 06151 char *stringp=NULL; 06152 06153 if (!value) 06154 return -1; 06155 ast_copy_string(copy, value, sizeof(copy)); 06156 stringp=copy; 06157 username = strsep(&stringp, "@"); 06158 hostname = strsep(&stringp, "@"); 06159 if (!hostname) { 06160 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 06161 return -1; 06162 } 06163 stringp=username; 06164 username = strsep(&stringp, ":"); 06165 secret = strsep(&stringp, ":"); 06166 stringp=hostname; 06167 hostname = strsep(&stringp, ":"); 06168 porta = strsep(&stringp, ":"); 06169 06170 if (porta && !atoi(porta)) { 06171 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 06172 return -1; 06173 } 06174 if (!(reg = ast_calloc(1, sizeof(*reg)))) 06175 return -1; 06176 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) { 06177 free(reg); 06178 return -1; 06179 } 06180 ast_copy_string(reg->username, username, sizeof(reg->username)); 06181 if (secret) 06182 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 06183 reg->expire = -1; 06184 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 06185 reg->addr.sin_family = AF_INET; 06186 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 06187 AST_LIST_LOCK(®istrations); 06188 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 06189 AST_LIST_UNLOCK(®istrations); 06190 06191 return 0; 06192 }
static int iax2_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 10459 of file chan_iax2.c.
References reload_config().
10460 { 10461 return reload_config(); 10462 }
static struct ast_channel * iax2_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 9159 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.
09160 { 09161 int callno; 09162 int res; 09163 int fmt, native; 09164 struct sockaddr_in sin; 09165 struct ast_channel *c; 09166 struct parsed_dial_string pds; 09167 struct create_addr_info cai; 09168 char *tmpstr; 09169 09170 memset(&pds, 0, sizeof(pds)); 09171 tmpstr = ast_strdupa(data); 09172 parse_dial_string(tmpstr, &pds); 09173 09174 if (ast_strlen_zero(pds.peer)) { 09175 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 09176 return NULL; 09177 } 09178 09179 memset(&cai, 0, sizeof(cai)); 09180 cai.capability = iax2_capability; 09181 09182 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09183 09184 /* Populate our address from the given */ 09185 if (create_addr(pds.peer, NULL, &sin, &cai)) { 09186 *cause = AST_CAUSE_UNREGISTERED; 09187 return NULL; 09188 } 09189 09190 if (pds.port) 09191 sin.sin_port = htons(atoi(pds.port)); 09192 09193 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 09194 if (callno < 1) { 09195 ast_log(LOG_WARNING, "Unable to create call\n"); 09196 *cause = AST_CAUSE_CONGESTION; 09197 return NULL; 09198 } 09199 09200 /* If this is a trunk, update it now */ 09201 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09202 if (ast_test_flag(&cai, IAX_TRUNK)) { 09203 int new_callno; 09204 if ((new_callno = make_trunk(callno, 1)) != -1) 09205 callno = new_callno; 09206 } 09207 iaxs[callno]->maxtime = cai.maxtime; 09208 if (cai.found) 09209 ast_string_field_set(iaxs[callno], host, pds.peer); 09210 09211 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 09212 09213 ast_mutex_unlock(&iaxsl[callno]); 09214 09215 if (c) { 09216 /* Choose a format we can live with */ 09217 if (c->nativeformats & format) 09218 c->nativeformats &= format; 09219 else { 09220 native = c->nativeformats; 09221 fmt = format; 09222 res = ast_translator_best_choice(&fmt, &native); 09223 if (res < 0) { 09224 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 09225 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 09226 ast_hangup(c); 09227 return NULL; 09228 } 09229 c->nativeformats = native; 09230 } 09231 c->readformat = ast_best_codec(c->nativeformats); 09232 c->writeformat = c->readformat; 09233 } 09234 09235 return c; 09236 }
static int iax2_sched_add | ( | struct sched_context * | con, | |
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 993 of file chan_iax2.c.
References ast_cond_signal(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), and sched_lock.
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_hangup(), iax2_poke_peer(), iax2_provision(), make_trunk(), network_thread(), reg_source_db(), socket_process(), update_jbsched(), and update_registry().
00994 { 00995 int res; 00996 00997 ast_mutex_lock(&sched_lock); 00998 res = ast_sched_add(con, when, callback, data); 00999 ast_cond_signal(&sched_cond); 01000 ast_mutex_unlock(&sched_lock); 01001 01002 return res; 01003 }
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 4460 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().
04461 { 04462 /* Queue a packet for delivery on a given private structure. Use "ts" for 04463 timestamp, or calculate if ts is 0. Send immediately without retransmission 04464 or delayed, with retransmission */ 04465 struct ast_iax2_full_hdr *fh; 04466 struct ast_iax2_mini_hdr *mh; 04467 struct ast_iax2_video_hdr *vh; 04468 struct { 04469 struct iax_frame fr2; 04470 unsigned char buffer[4096]; 04471 } frb; 04472 struct iax_frame *fr; 04473 int res; 04474 int sendmini=0; 04475 unsigned int lastsent; 04476 unsigned int fts; 04477 04478 frb.fr2.afdatalen = sizeof(frb.buffer); 04479 04480 if (!pvt) { 04481 ast_log(LOG_WARNING, "No private structure for packet?\n"); 04482 return -1; 04483 } 04484 04485 lastsent = pvt->lastsent; 04486 04487 /* Calculate actual timestamp */ 04488 fts = calc_timestamp(pvt, ts, f); 04489 04490 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 04491 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 04492 * increment the "predicted timestamps" for voice, if we're predecting */ 04493 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 04494 return 0; 04495 04496 04497 if ((ast_test_flag(pvt, IAX_TRUNK) || 04498 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 04499 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 04500 /* High two bytes are the same on timestamp, or sending on a trunk */ && 04501 (f->frametype == AST_FRAME_VOICE) 04502 /* is a voice frame */ && 04503 (f->subclass == pvt->svoiceformat) 04504 /* is the same type */ ) { 04505 /* Force immediate rather than delayed transmission */ 04506 now = 1; 04507 /* Mark that mini-style frame is appropriate */ 04508 sendmini = 1; 04509 } 04510 if ( f->frametype == AST_FRAME_VIDEO ) { 04511 /* 04512 * If the lower 15 bits of the timestamp roll over, or if 04513 * the video format changed then send a full frame. 04514 * Otherwise send a mini video frame 04515 */ 04516 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 04517 ((f->subclass & ~0x1) == pvt->svideoformat) 04518 ) { 04519 now = 1; 04520 sendmini = 1; 04521 } else { 04522 now = 0; 04523 sendmini = 0; 04524 } 04525 pvt->lastvsent = fts; 04526 } 04527 /* Allocate an iax_frame */ 04528 if (now) { 04529 fr = &frb.fr2; 04530 } else 04531 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)); 04532 if (!fr) { 04533 ast_log(LOG_WARNING, "Out of memory\n"); 04534 return -1; 04535 } 04536 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 04537 iax_frame_wrap(fr, f); 04538 04539 fr->ts = fts; 04540 fr->callno = pvt->callno; 04541 fr->transfer = transfer; 04542 fr->final = final; 04543 if (!sendmini) { 04544 /* We need a full frame */ 04545 if (seqno > -1) 04546 fr->oseqno = seqno; 04547 else 04548 fr->oseqno = pvt->oseqno++; 04549 fr->iseqno = pvt->iseqno; 04550 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr)); 04551 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 04552 fh->ts = htonl(fr->ts); 04553 fh->oseqno = fr->oseqno; 04554 if (transfer) { 04555 fh->iseqno = 0; 04556 } else 04557 fh->iseqno = fr->iseqno; 04558 /* Keep track of the last thing we've acknowledged */ 04559 if (!transfer) 04560 pvt->aseqno = fr->iseqno; 04561 fh->type = fr->af.frametype & 0xFF; 04562 if (fr->af.frametype == AST_FRAME_VIDEO) 04563 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 04564 else 04565 fh->csub = compress_subclass(fr->af.subclass); 04566 if (transfer) { 04567 fr->dcallno = pvt->transfercallno; 04568 } else 04569 fr->dcallno = pvt->peercallno; 04570 fh->dcallno = htons(fr->dcallno); 04571 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 04572 fr->data = fh; 04573 fr->retries = 0; 04574 /* Retry after 2x the ping time has passed */ 04575 fr->retrytime = pvt->pingtime * 2; 04576 if (fr->retrytime < MIN_RETRY_TIME) 04577 fr->retrytime = MIN_RETRY_TIME; 04578 if (fr->retrytime > MAX_RETRY_TIME) 04579 fr->retrytime = MAX_RETRY_TIME; 04580 /* Acks' don't get retried */ 04581 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 04582 fr->retries = -1; 04583 else if (f->frametype == AST_FRAME_VOICE) 04584 pvt->svoiceformat = f->subclass; 04585 else if (f->frametype == AST_FRAME_VIDEO) 04586 pvt->svideoformat = f->subclass & ~0x1; 04587 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04588 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04589 if (iaxdebug) { 04590 if (fr->transfer) 04591 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04592 else 04593 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04594 } 04595 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 04596 } else 04597 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04598 } 04599 04600 if (now) { 04601 res = send_packet(fr); 04602 } else 04603 res = iax2_transmit(fr); 04604 } else { 04605 if (ast_test_flag(pvt, IAX_TRUNK)) { 04606 iax2_trunk_queue(pvt, fr); 04607 res = 0; 04608 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 04609 /* Video frame have no sequence number */ 04610 fr->oseqno = -1; 04611 fr->iseqno = -1; 04612 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr)); 04613 vh->zeros = 0; 04614 vh->callno = htons(0x8000 | fr->callno); 04615 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 04616 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 04617 fr->data = vh; 04618 fr->retries = -1; 04619 res = send_packet(fr); 04620 } else { 04621 /* Mini-frames have no sequence number */ 04622 fr->oseqno = -1; 04623 fr->iseqno = -1; 04624 /* Mini frame will do */ 04625 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr)); 04626 mh->callno = htons(fr->callno); 04627 mh->ts = htons(fr->ts & 0xFFFF); 04628 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 04629 fr->data = mh; 04630 fr->retries = -1; 04631 if (pvt->transferring == TRANSFER_MEDIAPASS) 04632 fr->transfer = 1; 04633 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04634 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04635 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 04636 } else 04637 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04638 } 04639 res = send_packet(fr); 04640 } 04641 } 04642 return res; 04643 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 2905 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02906 { 02907 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 02908 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 2900 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.
02901 { 02902 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1); 02903 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 2893 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02894 { 02895 02896 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 02897 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 02898 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 3578 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().
03579 { 03580 struct ast_option_header *h; 03581 int res; 03582 03583 switch (option) { 03584 case AST_OPTION_TXGAIN: 03585 case AST_OPTION_RXGAIN: 03586 /* these two cannot be sent, because they require a result */ 03587 errno = ENOSYS; 03588 return -1; 03589 default: 03590 { 03591 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03592 struct chan_iax2_pvt *pvt; 03593 03594 ast_mutex_lock(&iaxsl[callno]); 03595 pvt = iaxs[callno]; 03596 03597 if (wait_for_peercallno(pvt)) { 03598 ast_mutex_unlock(&iaxsl[callno]); 03599 return -1; 03600 } 03601 03602 ast_mutex_unlock(&iaxsl[callno]); 03603 03604 if (!(h = ast_malloc(datalen + sizeof(*h)))) { 03605 return -1; 03606 } 03607 03608 h->flag = AST_OPTION_FLAG_REQUEST; 03609 h->option = htons(option); 03610 memcpy(h->data, data, datalen); 03611 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 03612 AST_CONTROL_OPTION, 0, (unsigned char *) h, 03613 datalen + sizeof(*h), -1); 03614 free(h); 03615 return res; 03616 } 03617 } 03618 }
static int iax2_show_cache | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2578 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.
02579 { 02580 struct iax2_dpcache *dp; 02581 char tmp[1024], *pc; 02582 int s; 02583 int x,y; 02584 struct timeval tv; 02585 gettimeofday(&tv, NULL); 02586 ast_mutex_lock(&dpcache_lock); 02587 dp = dpcache; 02588 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 02589 while(dp) { 02590 s = dp->expiry.tv_sec - tv.tv_sec; 02591 tmp[0] = '\0'; 02592 if (dp->flags & CACHE_FLAG_EXISTS) 02593 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 02594 if (dp->flags & CACHE_FLAG_NONEXISTENT) 02595 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 02596 if (dp->flags & CACHE_FLAG_CANEXIST) 02597 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 02598 if (dp->flags & CACHE_FLAG_PENDING) 02599 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 02600 if (dp->flags & CACHE_FLAG_TIMEOUT) 02601 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 02602 if (dp->flags & CACHE_FLAG_TRANSMITTED) 02603 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 02604 if (dp->flags & CACHE_FLAG_MATCHMORE) 02605 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 02606 if (dp->flags & CACHE_FLAG_UNKNOWN) 02607 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 02608 /* Trim trailing pipe */ 02609 if (!ast_strlen_zero(tmp)) 02610 tmp[strlen(tmp) - 1] = '\0'; 02611 else 02612 ast_copy_string(tmp, "(none)", sizeof(tmp)); 02613 y=0; 02614 pc = strchr(dp->peercontext, '@'); 02615 if (!pc) 02616 pc = dp->peercontext; 02617 else 02618 pc++; 02619 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 02620 if (dp->waiters[x] > -1) 02621 y++; 02622 if (s > 0) 02623 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 02624 else 02625 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 02626 dp = dp->next; 02627 } 02628 ast_mutex_unlock(&dpcache_lock); 02629 return RESULT_SUCCESS; 02630 }
static int iax2_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4987 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.
04988 { 04989 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" 04990 #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" 04991 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 04992 int x; 04993 int numchans = 0; 04994 04995 if (argc != 3) 04996 return RESULT_SHOWUSAGE; 04997 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format"); 04998 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 04999 ast_mutex_lock(&iaxsl[x]); 05000 if (iaxs[x]) { 05001 int lag, jitter, localdelay; 05002 jb_info jbinfo; 05003 05004 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 05005 jb_getinfo(iaxs[x]->jb, &jbinfo); 05006 jitter = jbinfo.jitter; 05007 localdelay = jbinfo.current - jbinfo.min; 05008 } else { 05009 jitter = -1; 05010 localdelay = 0; 05011 } 05012 lag = iaxs[x]->remote_rr.delay; 05013 ast_cli(fd, FORMAT, 05014 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 05015 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 05016 S_OR(iaxs[x]->username, "(None)"), 05017 iaxs[x]->callno, iaxs[x]->peercallno, 05018 iaxs[x]->oseqno, iaxs[x]->iseqno, 05019 lag, 05020 jitter, 05021 localdelay, 05022 ast_getformatname(iaxs[x]->voiceformat) ); 05023 numchans++; 05024 } 05025 ast_mutex_unlock(&iaxsl[x]); 05026 } 05027 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 05028 return RESULT_SUCCESS; 05029 #undef FORMAT 05030 #undef FORMAT2 05031 #undef FORMATB 05032 }
static int iax2_show_firmware | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4898 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.
04899 { 04900 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" 04901 #if !defined(__FreeBSD__) 04902 #define FORMAT "%-15.15s %-15d %-15d\n" 04903 #else /* __FreeBSD__ */ 04904 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */ 04905 #endif /* __FreeBSD__ */ 04906 struct iax_firmware *cur; 04907 if ((argc != 3) && (argc != 4)) 04908 return RESULT_SHOWUSAGE; 04909 ast_mutex_lock(&waresl.lock); 04910 04911 ast_cli(fd, FORMAT2, "Device", "Version", "Size"); 04912 for (cur = waresl.wares;cur;cur = cur->next) { 04913 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 04914 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version), 04915 (int)ntohl(cur->fwh->datalen)); 04916 } 04917 ast_mutex_unlock(&waresl.lock); 04918 return RESULT_SUCCESS; 04919 #undef FORMAT 04920 #undef FORMAT2 04921 }
static int iax2_show_netstats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5110 of file chan_iax2.c.
References ast_cli(), ast_cli_netstats(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05111 { 05112 int numchans = 0; 05113 if (argc != 3) 05114 return RESULT_SHOWUSAGE; 05115 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 05116 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n"); 05117 numchans = ast_cli_netstats(NULL, fd, 1); 05118 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 05119 return RESULT_SUCCESS; 05120 }
static int iax2_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 2468 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.
02469 { 02470 char status[30]; 02471 char cbuf[256]; 02472 struct iax2_peer *peer; 02473 char codec_buf[512]; 02474 int x = 0, codec = 0, load_realtime = 0; 02475 02476 if (argc < 4) 02477 return RESULT_SHOWUSAGE; 02478 02479 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 02480 02481 peer = find_peer(argv[3], load_realtime); 02482 if (peer) { 02483 ast_cli(fd,"\n\n"); 02484 ast_cli(fd, " * Name : %s\n", peer->name); 02485 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 02486 ast_cli(fd, " Context : %s\n", peer->context); 02487 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 02488 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No"); 02489 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 02490 ast_cli(fd, " Expire : %d\n", peer->expire); 02491 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 02492 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)); 02493 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 02494 ast_cli(fd, " Username : %s\n", peer->username); 02495 ast_cli(fd, " Codecs : "); 02496 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 02497 ast_cli(fd, "%s\n", codec_buf); 02498 02499 ast_cli(fd, " Codec Order : ("); 02500 for(x = 0; x < 32 ; x++) { 02501 codec = ast_codec_pref_index(&peer->prefs,x); 02502 if(!codec) 02503 break; 02504 ast_cli(fd, "%s", ast_getformatname(codec)); 02505 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 02506 ast_cli(fd, "|"); 02507 } 02508 02509 if (!x) 02510 ast_cli(fd, "none"); 02511 ast_cli(fd, ")\n"); 02512 02513 ast_cli(fd, " Status : "); 02514 peer_status(peer, status, sizeof(status)); 02515 ast_cli(fd, "%s\n",status); 02516 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 02517 ast_cli(fd,"\n"); 02518 peer_unref(peer); 02519 } else { 02520 ast_cli(fd,"Peer %s not found.\n", argv[3]); 02521 ast_cli(fd,"\n"); 02522 } 02523 02524 return RESULT_SUCCESS; 02525 }
static int iax2_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4887 of file chan_iax2.c.
References __iax2_show_peers().
04888 { 04889 return __iax2_show_peers(0, fd, NULL, argc, argv); 04890 }
static int iax2_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4959 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.
04960 { 04961 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 04962 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 04963 struct iax2_registry *reg = NULL; 04964 04965 char host[80]; 04966 char perceived[80]; 04967 if (argc != 3) 04968 return RESULT_SHOWUSAGE; 04969 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 04970 AST_LIST_LOCK(®istrations); 04971 AST_LIST_TRAVERSE(®istrations, reg, entry) { 04972 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 04973 if (reg->us.sin_addr.s_addr) 04974 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 04975 else 04976 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 04977 ast_cli(fd, FORMAT, host, 04978 (reg->dnsmgr) ? "Y" : "N", 04979 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 04980 } 04981 AST_LIST_UNLOCK(®istrations); 04982 return RESULT_SUCCESS; 04983 #undef FORMAT 04984 #undef FORMAT2 04985 }
static int iax2_show_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2552 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.
02553 { 02554 struct iax_frame *cur; 02555 int cnt = 0, dead=0, final=0; 02556 02557 if (argc != 3) 02558 return RESULT_SHOWUSAGE; 02559 02560 AST_LIST_LOCK(&iaxq.queue); 02561 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 02562 if (cur->retries < 0) 02563 dead++; 02564 if (cur->final) 02565 final++; 02566 cnt++; 02567 } 02568 AST_LIST_UNLOCK(&iaxq.queue); 02569 02570 ast_cli(fd, " IAX Statistics\n"); 02571 ast_cli(fd, "---------------------\n"); 02572 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 02573 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 02574 02575 return RESULT_SUCCESS; 02576 }
static int iax2_show_threads | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4828 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.
04829 { 04830 struct iax2_thread *thread = NULL; 04831 time_t t; 04832 int threadcount = 0, dynamiccount = 0; 04833 char type; 04834 04835 if (argc != 3) 04836 return RESULT_SHOWUSAGE; 04837 04838 ast_cli(fd, "IAX2 Thread Information\n"); 04839 time(&t); 04840 ast_cli(fd, "Idle Threads:\n"); 04841 AST_LIST_LOCK(&idle_list); 04842 AST_LIST_TRAVERSE(&idle_list, thread, list) { 04843 #ifdef DEBUG_SCHED_MULTITHREAD 04844 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04845 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04846 #else 04847 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04848 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04849 #endif 04850 threadcount++; 04851 } 04852 AST_LIST_UNLOCK(&idle_list); 04853 ast_cli(fd, "Active Threads:\n"); 04854 AST_LIST_LOCK(&active_list); 04855 AST_LIST_TRAVERSE(&active_list, thread, list) { 04856 if (thread->type == IAX_TYPE_DYNAMIC) 04857 type = 'D'; 04858 else 04859 type = 'P'; 04860 #ifdef DEBUG_SCHED_MULTITHREAD 04861 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 04862 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04863 #else 04864 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 04865 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04866 #endif 04867 threadcount++; 04868 } 04869 AST_LIST_UNLOCK(&active_list); 04870 ast_cli(fd, "Dynamic Threads:\n"); 04871 AST_LIST_LOCK(&dynamic_list); 04872 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 04873 #ifdef DEBUG_SCHED_MULTITHREAD 04874 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04875 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04876 #else 04877 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04878 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04879 #endif 04880 dynamiccount++; 04881 } 04882 AST_LIST_UNLOCK(&dynamic_list); 04883 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 04884 return RESULT_SUCCESS; 04885 }
static int iax2_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4645 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().
04646 { 04647 regex_t regexbuf; 04648 int havepattern = 0; 04649 04650 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 04651 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 04652 04653 struct iax2_user *user = NULL; 04654 char auth[90]; 04655 char *pstr = ""; 04656 struct ao2_iterator i; 04657 04658 switch (argc) { 04659 case 5: 04660 if (!strcasecmp(argv[3], "like")) { 04661 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04662 return RESULT_SHOWUSAGE; 04663 havepattern = 1; 04664 } else 04665 return RESULT_SHOWUSAGE; 04666 case 3: 04667 break; 04668 default: 04669 return RESULT_SHOWUSAGE; 04670 } 04671 04672 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 04673 i = ao2_iterator_init(users, 0); 04674 for (user = ao2_iterator_next(&i); user; 04675 user_unref(user), user = ao2_iterator_next(&i)) { 04676 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 04677 continue; 04678 04679 if (!ast_strlen_zero(user->secret)) { 04680 ast_copy_string(auth,user->secret,sizeof(auth)); 04681 } else if (!ast_strlen_zero(user->inkeys)) { 04682 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 04683 } else 04684 ast_copy_string(auth, "-no secret-", sizeof(auth)); 04685 04686 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 04687 pstr = "REQ Only"; 04688 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 04689 pstr = "Disabled"; 04690 else 04691 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 04692 04693 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 04694 user->contexts ? user->contexts->context : context, 04695 user->ha ? "Yes" : "No", pstr); 04696 } 04697 04698 if (havepattern) 04699 regfree(®exbuf); 04700 04701 return RESULT_SUCCESS; 04702 #undef FORMAT 04703 #undef FORMAT2 04704 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 3626 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.
03627 { 03628 int res; 03629 struct iax_ie_data ied0; 03630 struct iax_ie_data ied1; 03631 unsigned int transferid = (unsigned int)ast_random(); 03632 memset(&ied0, 0, sizeof(ied0)); 03633 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 03634 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 03635 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 03636 03637 memset(&ied1, 0, sizeof(ied1)); 03638 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 03639 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 03640 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 03641 03642 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 03643 if (res) 03644 return -1; 03645 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 03646 if (res) 03647 return -1; 03648 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03649 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03650 return 0; 03651 }
static int iax2_test_losspct | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2399 of file chan_iax2.c.
References RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02400 { 02401 if (argc != 4) 02402 return RESULT_SHOWUSAGE; 02403 02404 test_losspct = atoi(argv[3]); 02405 02406 return RESULT_SUCCESS; 02407 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 3869 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.
03870 { 03871 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03872 struct iax_ie_data ied; 03873 char tmp[256], *context; 03874 ast_copy_string(tmp, dest, sizeof(tmp)); 03875 context = strchr(tmp, '@'); 03876 if (context) { 03877 *context = '\0'; 03878 context++; 03879 } 03880 memset(&ied, 0, sizeof(ied)); 03881 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 03882 if (context) 03883 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 03884 if (option_debug) 03885 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest); 03886 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 03887 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2864 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().
02865 { 02866 /* Lock the queue and place this packet at the end */ 02867 /* By setting this to 0, the network thread will send it for us, and 02868 queue retransmission if necessary */ 02869 fr->sentyet = 0; 02870 AST_LIST_LOCK(&iaxq.queue); 02871 AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list); 02872 iaxq.count++; 02873 AST_LIST_UNLOCK(&iaxq.queue); 02874 /* Wake up the network and scheduler thread */ 02875 if (netthreadid != AST_PTHREADT_NULL) 02876 pthread_kill(netthreadid, SIGURG); 02877 signal_condition(&sched_lock, &sched_cond); 02878 return 0; 02879 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 6724 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
06725 { 06726 /* Drop when trunk is about 5 seconds idle */ 06727 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 06728 return 1; 06729 return 0; 06730 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 4234 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().
04235 { 04236 struct ast_frame *f; 04237 struct iax2_trunk_peer *tpeer; 04238 void *tmp, *ptr; 04239 struct ast_iax2_meta_trunk_entry *met; 04240 struct ast_iax2_meta_trunk_mini *mtm; 04241 04242 f = &fr->af; 04243 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 04244 if (tpeer) { 04245 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 04246 /* Need to reallocate space */ 04247 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) { 04248 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 04249 ast_mutex_unlock(&tpeer->lock); 04250 return -1; 04251 } 04252 04253 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 04254 tpeer->trunkdata = tmp; 04255 if (option_debug) 04256 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); 04257 } else { 04258 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)); 04259 ast_mutex_unlock(&tpeer->lock); 04260 return -1; 04261 } 04262 } 04263 04264 /* Append to meta frame */ 04265 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 04266 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 04267 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 04268 mtm->len = htons(f->datalen); 04269 mtm->mini.callno = htons(pvt->callno); 04270 mtm->mini.ts = htons(0xffff & fr->ts); 04271 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 04272 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 04273 } else { 04274 met = (struct ast_iax2_meta_trunk_entry *)ptr; 04275 /* Store call number and length in meta header */ 04276 met->callno = htons(pvt->callno); 04277 met->len = htons(f->datalen); 04278 /* Advance pointers/decrease length past trunk entry header */ 04279 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 04280 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 04281 } 04282 /* Copy actual trunk data */ 04283 memcpy(ptr, f->data, f->datalen); 04284 tpeer->trunkdatalen += f->datalen; 04285 04286 tpeer->calls++; 04287 ast_mutex_unlock(&tpeer->lock); 04288 } 04289 return 0; 04290 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 6641 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, iaxs, and send_command_immediate().
Referenced by socket_process().
06642 { 06643 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 06644 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 5177 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.
05178 { 05179 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05180 int res = -1; 05181 ast_mutex_lock(&iaxsl[callno]); 05182 if (iaxs[callno]) { 05183 /* If there's an outstanding error, return failure now */ 05184 if (!iaxs[callno]->error) { 05185 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 05186 res = 0; 05187 /* Don't waste bandwidth sending null frames */ 05188 else if (f->frametype == AST_FRAME_NULL) 05189 res = 0; 05190 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 05191 res = 0; 05192 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 05193 res = 0; 05194 else 05195 /* Simple, just queue for transmission */ 05196 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 05197 } else { 05198 if (option_debug) 05199 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); 05200 } 05201 } 05202 /* If it's already gone, just return */ 05203 ast_mutex_unlock(&iaxsl[callno]); 05204 return res; 05205 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 2015 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().
02016 { 02017 int res = 0; 02018 struct iax_firmware *cur; 02019 if (!ast_strlen_zero(dev)) { 02020 ast_mutex_lock(&waresl.lock); 02021 cur = waresl.wares; 02022 while(cur) { 02023 if (!strcmp(dev, (char *)cur->fwh->devname)) { 02024 res = ntohs(cur->fwh->version); 02025 break; 02026 } 02027 cur = cur->next; 02028 } 02029 ast_mutex_unlock(&waresl.lock); 02030 } 02031 return res; 02032 }
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 2034 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().
02035 { 02036 int res = -1; 02037 unsigned int bs = desc & 0xff; 02038 unsigned int start = (desc >> 8) & 0xffffff; 02039 unsigned int bytes; 02040 struct iax_firmware *cur; 02041 if (!ast_strlen_zero((char *)dev) && bs) { 02042 start *= bs; 02043 ast_mutex_lock(&waresl.lock); 02044 cur = waresl.wares; 02045 while(cur) { 02046 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) { 02047 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 02048 if (start < ntohl(cur->fwh->datalen)) { 02049 bytes = ntohl(cur->fwh->datalen) - start; 02050 if (bytes > bs) 02051 bytes = bs; 02052 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 02053 } else { 02054 bytes = 0; 02055 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 02056 } 02057 if (bytes == bs) 02058 res = 0; 02059 else 02060 res = 1; 02061 break; 02062 } 02063 cur = cur->next; 02064 } 02065 ast_mutex_unlock(&waresl.lock); 02066 } 02067 return res; 02068 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2 | |||
) | [static] |
Definition at line 6912 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().
06913 { 06914 struct iax_dual *d; 06915 struct ast_channel *chan1m, *chan2m; 06916 pthread_t th; 06917 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 06918 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name); 06919 if (chan2m && chan1m) { 06920 /* Make formats okay */ 06921 chan1m->readformat = chan1->readformat; 06922 chan1m->writeformat = chan1->writeformat; 06923 ast_channel_masquerade(chan1m, chan1); 06924 /* Setup the extensions and such */ 06925 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 06926 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 06927 chan1m->priority = chan1->priority; 06928 06929 /* We make a clone of the peer channel too, so we can play 06930 back the announcement */ 06931 /* Make formats okay */ 06932 chan2m->readformat = chan2->readformat; 06933 chan2m->writeformat = chan2->writeformat; 06934 ast_channel_masquerade(chan2m, chan2); 06935 /* Setup the extensions and such */ 06936 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 06937 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 06938 chan2m->priority = chan2->priority; 06939 if (ast_do_masquerade(chan2m)) { 06940 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 06941 ast_hangup(chan2m); 06942 return -1; 06943 } 06944 } else { 06945 if (chan1m) 06946 ast_hangup(chan1m); 06947 if (chan2m) 06948 ast_hangup(chan2m); 06949 return -1; 06950 } 06951 if ((d = ast_calloc(1, sizeof(*d)))) { 06952 pthread_attr_t attr; 06953 06954 pthread_attr_init(&attr); 06955 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06956 06957 d->chan1 = chan1m; 06958 d->chan2 = chan2m; 06959 if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) { 06960 pthread_attr_destroy(&attr); 06961 return 0; 06962 } 06963 pthread_attr_destroy(&attr); 06964 free(d); 06965 } 06966 return -1; 06967 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 6892 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().
06893 { 06894 struct ast_channel *chan1, *chan2; 06895 struct iax_dual *d; 06896 struct ast_frame *f; 06897 int ext; 06898 int res; 06899 d = stuff; 06900 chan1 = d->chan1; 06901 chan2 = d->chan2; 06902 free(d); 06903 f = ast_read(chan1); 06904 if (f) 06905 ast_frfree(f); 06906 res = ast_park_call(chan1, chan2, 0, &ext); 06907 ast_hangup(chan2); 06908 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 06909 return NULL; 06910 }
Definition at line 1479 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().
01480 { 01481 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01482 if (new) { 01483 size_t afdatalen = new->afdatalen; 01484 memcpy(new, fr, sizeof(*new)); 01485 iax_frame_wrap(new, &fr->af); 01486 new->afdatalen = afdatalen; 01487 new->data = NULL; 01488 new->datalen = 0; 01489 new->direction = DIRECTION_INGRESS; 01490 new->retrans = -1; 01491 } 01492 return new; 01493 }
static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 901 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().
00902 { 00903 if (thread->type == IAX_TYPE_DYNAMIC) { 00904 AST_LIST_LOCK(&dynamic_list); 00905 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 00906 AST_LIST_UNLOCK(&dynamic_list); 00907 } else { 00908 AST_LIST_LOCK(&idle_list); 00909 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 00910 AST_LIST_UNLOCK(&idle_list); 00911 } 00912 00913 return; 00914 }
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 11321 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(), iax_transfercallno_pvts, 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(), transfercallno_pvt_cmp_cb(), transfercallno_pvt_hash_cb(), user_cmp_cb(), user_hash_cb(), VERBOSE_PREFIX_2, and waresl.
11322 { 11323 char *config = "iax.conf"; 11324 int res = 0; 11325 int x; 11326 struct iax2_registry *reg = NULL; 11327 11328 peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb); 11329 if (!peers) 11330 return AST_MODULE_LOAD_FAILURE; 11331 users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb); 11332 if (!users) { 11333 ao2_ref(peers, -1); 11334 return AST_MODULE_LOAD_FAILURE; 11335 } 11336 iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb); 11337 if (!iax_peercallno_pvts) { 11338 ao2_ref(peers, -1); 11339 ao2_ref(users, -1); 11340 return AST_MODULE_LOAD_FAILURE; 11341 } 11342 iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb); 11343 if (!iax_transfercallno_pvts) { 11344 ao2_ref(peers, -1); 11345 ao2_ref(users, -1); 11346 ao2_ref(iax_peercallno_pvts, -1); 11347 return AST_MODULE_LOAD_FAILURE; 11348 } 11349 ast_custom_function_register(&iaxpeer_function); 11350 11351 iax_set_output(iax_debug_output); 11352 iax_set_error(iax_error_output); 11353 jb_setoutput(jb_error_output, jb_warning_output, NULL); 11354 11355 #ifdef HAVE_DAHDI 11356 #ifdef DAHDI_TIMERACK 11357 timingfd = open(DAHDI_FILE_TIMER, O_RDWR); 11358 if (timingfd < 0) 11359 #endif 11360 timingfd = open(DAHDI_FILE_PSEUDO, O_RDWR); 11361 if (timingfd < 0) 11362 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno)); 11363 #endif 11364 11365 memset(iaxs, 0, sizeof(iaxs)); 11366 11367 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 11368 ast_mutex_init(&iaxsl[x]); 11369 } 11370 11371 ast_cond_init(&sched_cond, NULL); 11372 11373 io = io_context_create(); 11374 sched = sched_context_create(); 11375 11376 if (!io || !sched) { 11377 ast_log(LOG_ERROR, "Out of memory\n"); 11378 return -1; 11379 } 11380 11381 netsock = ast_netsock_list_alloc(); 11382 if (!netsock) { 11383 ast_log(LOG_ERROR, "Could not allocate netsock list.\n"); 11384 return -1; 11385 } 11386 ast_netsock_init(netsock); 11387 11388 outsock = ast_netsock_list_alloc(); 11389 if (!outsock) { 11390 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 11391 return -1; 11392 } 11393 ast_netsock_init(outsock); 11394 11395 ast_mutex_init(&waresl.lock); 11396 11397 AST_LIST_HEAD_INIT(&iaxq.queue); 11398 11399 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 11400 11401 ast_register_application(papp, iax2_prov_app, psyn, pdescrip); 11402 11403 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" ); 11404 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" ); 11405 11406 if(set_config(config, 0) == -1) 11407 return AST_MODULE_LOAD_DECLINE; 11408 11409 if (ast_channel_register(&iax2_tech)) { 11410 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 11411 __unload_module(); 11412 return -1; 11413 } 11414 11415 if (ast_register_switch(&iax2_switch)) 11416 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 11417 11418 res = start_network_thread(); 11419 if (!res) { 11420 if (option_verbose > 1) 11421 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n"); 11422 } else { 11423 ast_log(LOG_ERROR, "Unable to start network thread\n"); 11424 ast_netsock_release(netsock); 11425 ast_netsock_release(outsock); 11426 } 11427 11428 AST_LIST_LOCK(®istrations); 11429 AST_LIST_TRAVERSE(®istrations, reg, entry) 11430 iax2_do_register(reg); 11431 AST_LIST_UNLOCK(®istrations); 11432 11433 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 11434 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 11435 11436 reload_firmware(0); 11437 iax_provision_reload(); 11438 return res; 11439 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3653 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), DEADLOCK_AVOIDANCE, and iaxsl.
Referenced by iax2_bridge().
03654 { 03655 ast_mutex_lock(&iaxsl[callno0]); 03656 while (ast_mutex_trylock(&iaxsl[callno1])) { 03657 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 03658 } 03659 }
static int make_trunk | ( | unsigned short | callno, | |
int | locked | |||
) | [static] |
Definition at line 1533 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().
01534 { 01535 int x; 01536 int res= 0; 01537 struct timeval now; 01538 if (iaxs[callno]->oseqno) { 01539 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 01540 return -1; 01541 } 01542 if (callno & TRUNK_CALL_START) { 01543 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01544 return -1; 01545 } 01546 gettimeofday(&now, NULL); 01547 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 01548 ast_mutex_lock(&iaxsl[x]); 01549 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01550 /* Update the two timers that should have been started */ 01551 /*! 01552 * \note We delete these before switching the slot, because if 01553 * they fire in the meantime, they will generate a warning. 01554 */ 01555 AST_SCHED_DEL(sched, iaxs[callno]->pingid); 01556 AST_SCHED_DEL(sched, iaxs[callno]->lagid); 01557 iaxs[x] = iaxs[callno]; 01558 iaxs[x]->callno = x; 01559 iaxs[callno] = NULL; 01560 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01561 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01562 if (locked) 01563 ast_mutex_unlock(&iaxsl[callno]); 01564 res = x; 01565 if (!locked) 01566 ast_mutex_unlock(&iaxsl[x]); 01567 break; 01568 } 01569 ast_mutex_unlock(&iaxsl[x]); 01570 } 01571 if (x >= ARRAY_LEN(iaxs) - 1) { 01572 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01573 return -1; 01574 } 01575 if (option_debug) 01576 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x); 01577 /* We move this call from a non-trunked to a trunked call */ 01578 update_max_trunk(); 01579 update_max_nontrunk(); 01580 return res; 01581 }
static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4891 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), RESULT_SUCCESS, and s.
Referenced by load_module().
04892 { 04893 ast_cli_netstats(s, -1, 0); 04894 astman_append(s, "\r\n"); 04895 return RESULT_SUCCESS; 04896 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4924 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), and s.
Referenced by load_module().
04925 { 04926 char *a[] = { "iax2", "show", "users" }; 04927 int ret; 04928 const char *id = astman_get_header(m,"ActionID"); 04929 04930 if (!ast_strlen_zero(id)) 04931 astman_append(s, "ActionID: %s\r\n",id); 04932 ret = __iax2_show_peers(1, -1, s, 3, a ); 04933 astman_append(s, "\r\n\r\n" ); 04934 return ret; 04935 } /* /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 1499 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(), softhangup_exec(), and transfercallno_pvt_cmp_cb().
01500 { 01501 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01502 (cur->addr.sin_port == sin->sin_port)) { 01503 /* This is the main host */ 01504 if ( (cur->peercallno == 0 || cur->peercallno == callno) && 01505 (check_dcallno ? dcallno == cur->callno : 1) ) { 01506 /* That's us. Be sure we keep track of the peer call number */ 01507 return 1; 01508 } 01509 } 01510 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01511 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01512 /* We're transferring */ 01513 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 01514 return 1; 01515 } 01516 return 0; 01517 }
static void memcpy_decrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 4298 of file chan_iax2.c.
References aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
04299 { 04300 #if 0 04301 /* Debug with "fake encryption" */ 04302 int x; 04303 if (len % 16) 04304 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 04305 for (x=0;x<len;x++) 04306 dst[x] = src[x] ^ 0xff; 04307 #else 04308 unsigned char lastblock[16] = { 0 }; 04309 int x; 04310 while(len > 0) { 04311 aes_decrypt(src, dst, dcx); 04312 for (x=0;x<16;x++) 04313 dst[x] ^= lastblock[x]; 04314 memcpy(lastblock, src, sizeof(lastblock)); 04315 dst += 16; 04316 src += 16; 04317 len -= 16; 04318 } 04319 #endif 04320 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_encrypt_ctx * | ecx | |||
) | [static] |
Definition at line 4322 of file chan_iax2.c.
References aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
04323 { 04324 #if 0 04325 /* Debug with "fake encryption" */ 04326 int x; 04327 if (len % 16) 04328 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 04329 for (x=0;x<len;x++) 04330 dst[x] = src[x] ^ 0xff; 04331 #else 04332 unsigned char curblock[16] = { 0 }; 04333 int x; 04334 while(len > 0) { 04335 for (x=0;x<16;x++) 04336 curblock[x] ^= src[x]; 04337 aes_encrypt(curblock, dst, ecx); 04338 memcpy(curblock, dst, sizeof(curblock)); 04339 dst += 16; 04340 src += 16; 04341 len -= 16; 04342 } 04343 #endif 04344 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 5499 of file chan_iax2.c.
References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.
Referenced by authenticate_reply(), and socket_process().
05500 { 05501 /* Select exactly one common encryption if there are any */ 05502 p->encmethods &= enc; 05503 if (p->encmethods) { 05504 if (p->encmethods & IAX_ENCRYPT_AES128) 05505 p->encmethods = IAX_ENCRYPT_AES128; 05506 else 05507 p->encmethods = 0; 05508 } 05509 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 9273 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().
09274 { 09275 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 09276 from the network, and queue them for delivery to the channels */ 09277 int res, count, wakeup; 09278 struct iax_frame *f; 09279 09280 if (timingfd > -1) 09281 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL); 09282 09283 for(;;) { 09284 pthread_testcancel(); 09285 09286 /* Go through the queue, sending messages which have not yet been 09287 sent, and scheduling retransmissions if appropriate */ 09288 AST_LIST_LOCK(&iaxq.queue); 09289 count = 0; 09290 wakeup = -1; 09291 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) { 09292 if (f->sentyet) 09293 continue; 09294 09295 /* Try to lock the pvt, if we can't... don't fret - defer it till later */ 09296 if (ast_mutex_trylock(&iaxsl[f->callno])) { 09297 wakeup = 1; 09298 continue; 09299 } 09300 09301 f->sentyet++; 09302 09303 if (iaxs[f->callno]) { 09304 send_packet(f); 09305 count++; 09306 } 09307 09308 ast_mutex_unlock(&iaxsl[f->callno]); 09309 09310 if (f->retries < 0) { 09311 /* This is not supposed to be retransmitted */ 09312 AST_LIST_REMOVE_CURRENT(&iaxq.queue, list); 09313 iaxq.count--; 09314 /* Free the iax frame */ 09315 iax_frame_free(f); 09316 } else { 09317 /* We need reliable delivery. Schedule a retransmission */ 09318 f->retries++; 09319 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 09320 } 09321 } 09322 AST_LIST_TRAVERSE_SAFE_END 09323 AST_LIST_UNLOCK(&iaxq.queue); 09324 09325 pthread_testcancel(); 09326 09327 if (option_debug && count >= 20) 09328 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 09329 09330 /* Now do the IO, and run scheduled tasks */ 09331 res = ast_io_wait(io, wakeup); 09332 if (res >= 0) { 09333 if (option_debug && res >= 20) 09334 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 09335 } 09336 } 09337 return NULL; 09338 }
static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
const char * | host | |||
) | [static] |
Definition at line 1440 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().
01441 { 01442 struct chan_iax2_pvt *tmp; 01443 jb_conf jbconf; 01444 01445 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) { 01446 return NULL; 01447 } 01448 01449 if (ast_string_field_init(tmp, 32)) { 01450 ao2_ref(tmp, -1); 01451 tmp = NULL; 01452 return NULL; 01453 } 01454 01455 tmp->prefs = prefs; 01456 tmp->callno = 0; 01457 tmp->peercallno = 0; 01458 tmp->transfercallno = 0; 01459 tmp->bridgecallno = 0; 01460 tmp->pingid = -1; 01461 tmp->lagid = -1; 01462 tmp->autoid = -1; 01463 tmp->authid = -1; 01464 tmp->initid = -1; 01465 01466 ast_string_field_set(tmp,exten, "s"); 01467 ast_string_field_set(tmp,host, host); 01468 01469 tmp->jb = jb_new(); 01470 tmp->jbid = -1; 01471 jbconf.max_jitterbuf = maxjitterbuffer; 01472 jbconf.resync_threshold = resyncthreshold; 01473 jbconf.max_contig_interp = maxjitterinterps; 01474 jb_setconf(tmp->jb,&jbconf); 01475 01476 return tmp; 01477 }
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 3324 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().
03325 { 03326 if (ast_strlen_zero(data)) 03327 return; 03328 03329 pds->peer = strsep(&data, "/"); 03330 pds->exten = strsep(&data, "/"); 03331 pds->options = data; 03332 03333 if (pds->exten) { 03334 data = pds->exten; 03335 pds->exten = strsep(&data, "@"); 03336 pds->context = data; 03337 } 03338 03339 if (strchr(pds->peer, '@')) { 03340 data = pds->peer; 03341 pds->username = strsep(&data, "@"); 03342 pds->peer = data; 03343 } 03344 03345 if (pds->username) { 03346 data = pds->username; 03347 pds->username = strsep(&data, ":"); 03348 pds->password = data; 03349 } 03350 03351 data = pds->peer; 03352 pds->peer = strsep(&data, ":"); 03353 pds->port = data; 03354 03355 /* check for a key name wrapped in [] in the secret position, if found, 03356 move it to the key field instead 03357 */ 03358 if (pds->password && (pds->password[0] == '[')) { 03359 pds->key = ast_strip_quoted(pds->password, "[", "]"); 03360 pds->password = NULL; 03361 } 03362 }
static int peer_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1130 of file chan_iax2.c.
References iax2_peer::name.
Referenced by load_module().
01131 { 01132 struct iax2_peer *peer = obj, *peer2 = arg; 01133 01134 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0; 01135 }
static int peer_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9963 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
09964 { 09965 struct iax2_peer *peer = obj; 09966 09967 ast_set_flag(peer, IAX_DELME); 09968 09969 return 0; 09970 }
static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 9496 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().
09497 { 09498 struct iax2_peer *peer = obj; 09499 int callno = peer->callno; 09500 09501 ast_free_ha(peer->ha); 09502 09503 if (callno > 0) { 09504 ast_mutex_lock(&iaxsl[callno]); 09505 iax2_destroy(callno); 09506 ast_mutex_unlock(&iaxsl[callno]); 09507 } 09508 09509 register_peer_exten(peer, 0); 09510 09511 if (peer->dnsmgr) 09512 ast_dnsmgr_release(peer->dnsmgr); 09513 09514 ast_string_field_free_memory(peer); 09515 }
static int peer_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1120 of file chan_iax2.c.
References ast_str_hash(), and iax2_peer::name.
Referenced by load_module().
01121 { 01122 const struct iax2_peer *peer = obj; 01123 01124 return ast_str_hash(peer->name); 01125 }
Definition at line 1177 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().
01178 { 01179 ao2_ref(peer, +1); 01180 return peer; 01181 }
static int peer_set_sock_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11275 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
11276 { 11277 struct iax2_peer *peer = obj; 11278 11279 if (peer->sockfd < 0) 11280 peer->sockfd = defaultsockfd; 11281 11282 return 0; 11283 }
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 9423 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().
09424 { 09425 struct sockaddr_in sin; 09426 int nonlocal = 1; 09427 int port = IAX_DEFAULT_PORTNO; 09428 int sockfd = defaultsockfd; 09429 char *tmp; 09430 char *addr; 09431 char *portstr; 09432 09433 if (!(tmp = ast_strdupa(srcaddr))) 09434 return -1; 09435 09436 addr = strsep(&tmp, ":"); 09437 portstr = tmp; 09438 09439 if (portstr) { 09440 port = atoi(portstr); 09441 if (port < 1) 09442 port = IAX_DEFAULT_PORTNO; 09443 } 09444 09445 if (!ast_get_ip(&sin, addr)) { 09446 struct ast_netsock *sock; 09447 int res; 09448 09449 sin.sin_port = 0; 09450 sin.sin_family = AF_INET; 09451 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 09452 if (res == 0) { 09453 /* ip address valid. */ 09454 sin.sin_port = htons(port); 09455 if (!(sock = ast_netsock_find(netsock, &sin))) 09456 sock = ast_netsock_find(outsock, &sin); 09457 if (sock) { 09458 sockfd = ast_netsock_sockfd(sock); 09459 nonlocal = 0; 09460 } else { 09461 unsigned int orig_saddr = sin.sin_addr.s_addr; 09462 /* INADDR_ANY matches anyway! */ 09463 sin.sin_addr.s_addr = INADDR_ANY; 09464 if (ast_netsock_find(netsock, &sin)) { 09465 sin.sin_addr.s_addr = orig_saddr; 09466 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL); 09467 if (sock) { 09468 sockfd = ast_netsock_sockfd(sock); 09469 ast_netsock_unref(sock); 09470 nonlocal = 0; 09471 } else { 09472 nonlocal = 2; 09473 } 09474 } 09475 } 09476 } 09477 } 09478 09479 peer->sockfd = sockfd; 09480 09481 if (nonlocal == 1) { 09482 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 09483 srcaddr, peer->name); 09484 return -1; 09485 } else if (nonlocal == 2) { 09486 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 09487 srcaddr, peer->name); 09488 return -1; 09489 } else { 09490 if (option_debug) 09491 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 09492 return 0; 09493 } 09494 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 2445 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().
02446 { 02447 int res = 0; 02448 if (peer->maxms) { 02449 if (peer->lastms < 0) { 02450 ast_copy_string(status, "UNREACHABLE", statuslen); 02451 } else if (peer->lastms > peer->maxms) { 02452 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 02453 res = 1; 02454 } else if (peer->lastms) { 02455 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 02456 res = 1; 02457 } else { 02458 ast_copy_string(status, "UNKNOWN", statuslen); 02459 } 02460 } else { 02461 ast_copy_string(status, "Unmonitored", statuslen); 02462 res = -1; 02463 } 02464 return res; 02465 }
Definition at line 1183 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().
01184 { 01185 ao2_ref(peer, -1); 01186 return NULL; 01187 }
static void poke_all_peers | ( | void | ) | [static] |
Definition at line 10427 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), iax2_poke_peer(), and peer_unref().
Referenced by reload_config().
10428 { 10429 struct ao2_iterator i; 10430 struct iax2_peer *peer; 10431 10432 i = ao2_iterator_init(peers, 0); 10433 while ((peer = ao2_iterator_next(&i))) { 10434 iax2_poke_peer(peer, 0); 10435 peer_unref(peer); 10436 } 10437 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 10023 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_test_flag, IAX_DELME, IAX_RTCACHEFRIENDS, peer_unref(), and unlink_peer().
10024 { 10025 struct iax2_peer *peer; 10026 struct ao2_iterator i; 10027 10028 i = ao2_iterator_init(peers, 0); 10029 while ((peer = ao2_iterator_next(&i))) { 10030 if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 10031 unlink_peer(peer); 10032 } 10033 peer_unref(peer); 10034 } 10035 }
static void prune_users | ( | void | ) | [static] |
Definition at line 10008 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ao2_unlink(), ast_test_flag, IAX_DELME, IAX_RTCACHEFRIENDS, and user_unref().
Referenced by iax2_prune_realtime(), and reload_config().
10009 { 10010 struct iax2_user *user; 10011 struct ao2_iterator i; 10012 10013 i = ao2_iterator_init(users, 0); 10014 while ((user = ao2_iterator_next(&i))) { 10015 if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) { 10016 ao2_unlink(users, user); 10017 } 10018 user_unref(user); 10019 } 10020 }
static int pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11292 of file chan_iax2.c.
References chan_iax2_pvt::frames_received, and match().
Referenced by load_module().
11293 { 11294 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 11295 11296 /* The frames_received field is used to hold whether we're matching 11297 * against a full frame or not ... */ 11298 11299 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 11300 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 11301 }
static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1401 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().
01402 { 01403 struct chan_iax2_pvt *pvt = obj; 01404 struct iax_frame *cur = NULL; 01405 01406 iax2_destroy_helper(pvt); 01407 01408 /* Already gone */ 01409 ast_set_flag(pvt, IAX_ALREADYGONE); 01410 01411 AST_LIST_LOCK(&iaxq.queue); 01412 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 01413 /* Cancel any pending transmissions */ 01414 if (cur->callno == pvt->callno) { 01415 cur->retries = -1; 01416 } 01417 } 01418 AST_LIST_UNLOCK(&iaxq.queue); 01419 01420 if (pvt->reg) { 01421 pvt->reg->callno = 0; 01422 } 01423 01424 if (!pvt->owner) { 01425 jb_frame frame; 01426 if (pvt->vars) { 01427 ast_variables_destroy(pvt->vars); 01428 pvt->vars = NULL; 01429 } 01430 01431 while (jb_getall(pvt->jb, &frame) == JB_OK) { 01432 iax2_frame_free(frame.data); 01433 } 01434 01435 jb_destroy(pvt->jb); 01436 ast_string_field_free_memory(pvt); 01437 } 01438 }
static int pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 11285 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
Referenced by load_module().
11286 { 11287 const struct chan_iax2_pvt *pvt = obj; 11288 11289 return pvt->peercallno; 11290 }
static int raw_hangup | ( | struct sockaddr_in * | sin, | |
unsigned short | src, | |||
unsigned short | dst, | |||
int | sockfd | |||
) | [static] |
Definition at line 5481 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().
05482 { 05483 struct ast_iax2_full_hdr fh; 05484 fh.scallno = htons(src | IAX_FLAG_FULL); 05485 fh.dcallno = htons(dst); 05486 fh.ts = 0; 05487 fh.oseqno = 0; 05488 fh.iseqno = 0; 05489 fh.type = AST_FRAME_IAX; 05490 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 05491 if (iaxdebug) 05492 iax_showframe(NULL, &fh, 0, sin, 0); 05493 if (option_debug) 05494 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n", 05495 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 05496 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 05497 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 2926 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.
02927 { 02928 struct ast_variable *var = NULL; 02929 struct ast_variable *tmp; 02930 struct iax2_peer *peer=NULL; 02931 time_t regseconds = 0, nowtime; 02932 int dynamic=0; 02933 02934 if (peername) { 02935 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL); 02936 if (!var && sin) 02937 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02938 } else if (sin) { 02939 char porta[25]; 02940 sprintf(porta, "%d", ntohs(sin->sin_port)); 02941 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02942 if (var) { 02943 /* We'll need the peer name in order to build the structure! */ 02944 for (tmp = var; tmp; tmp = tmp->next) { 02945 if (!strcasecmp(tmp->name, "name")) 02946 peername = tmp->value; 02947 } 02948 } 02949 } 02950 if (!var && peername) { /* Last ditch effort */ 02951 var = ast_load_realtime("iaxpeers", "name", peername, NULL); 02952 /*!\note 02953 * If this one loaded something, then we need to ensure that the host 02954 * field matched. The only reason why we can't have this as a criteria 02955 * is because we only have the IP address and the host field might be 02956 * set as a name (and the reverse PTR might not match). 02957 */ 02958 if (var && sin) { 02959 for (tmp = var; tmp; tmp = tmp->next) { 02960 if (!strcasecmp(tmp->name, "host")) { 02961 struct ast_hostent ahp; 02962 struct hostent *hp; 02963 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02964 /* No match */ 02965 ast_variables_destroy(var); 02966 var = NULL; 02967 } 02968 break; 02969 } 02970 } 02971 } 02972 } 02973 if (!var) 02974 return NULL; 02975 02976 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 02977 02978 if (!peer) { 02979 ast_variables_destroy(var); 02980 return NULL; 02981 } 02982 02983 for (tmp = var; tmp; tmp = tmp->next) { 02984 /* Make sure it's not a user only... */ 02985 if (!strcasecmp(tmp->name, "type")) { 02986 if (strcasecmp(tmp->value, "friend") && 02987 strcasecmp(tmp->value, "peer")) { 02988 /* Whoops, we weren't supposed to exist! */ 02989 peer = peer_unref(peer); 02990 break; 02991 } 02992 } else if (!strcasecmp(tmp->name, "regseconds")) { 02993 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 02994 } else if (!strcasecmp(tmp->name, "ipaddr")) { 02995 inet_aton(tmp->value, &(peer->addr.sin_addr)); 02996 } else if (!strcasecmp(tmp->name, "port")) { 02997 peer->addr.sin_port = htons(atoi(tmp->value)); 02998 } else if (!strcasecmp(tmp->name, "host")) { 02999 if (!strcasecmp(tmp->value, "dynamic")) 03000 dynamic = 1; 03001 } 03002 } 03003 03004 ast_variables_destroy(var); 03005 03006 if (!peer) 03007 return NULL; 03008 03009 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 03010 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 03011 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 03012 if (peer->expire > -1) { 03013 if (!ast_sched_del(sched, peer->expire)) { 03014 peer->expire = -1; 03015 peer_unref(peer); 03016 } 03017 } 03018 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 03019 if (peer->expire == -1) 03020 peer_unref(peer); 03021 } 03022 ao2_link(peers, peer); 03023 if (ast_test_flag(peer, IAX_DYNAMIC)) 03024 reg_source_db(peer); 03025 } else { 03026 ast_set_flag(peer, IAX_TEMPONLY); 03027 } 03028 03029 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 03030 time(&nowtime); 03031 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 03032 memset(&peer->addr, 0, sizeof(peer->addr)); 03033 realtime_update_peer(peer->name, &peer->addr, 0); 03034 if (option_debug) 03035 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 03036 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 03037 } 03038 else { 03039 if (option_debug) 03040 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 03041 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 03042 } 03043 } 03044 03045 return peer; 03046 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
time_t | regtime | |||
) | [static] |
Definition at line 3119 of file chan_iax2.c.
References ast_inet_ntoa(), and ast_update_realtime().
Referenced by __expire_registry(), update_peer(), and update_registry().
03120 { 03121 char port[10]; 03122 char regseconds[20]; 03123 03124 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 03125 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 03126 ast_update_realtime("iaxpeers", "name", peername, 03127 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 03128 "regseconds", regseconds, NULL); 03129 }
static struct iax2_user* realtime_user | ( | const char * | username, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 3048 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.
03049 { 03050 struct ast_variable *var; 03051 struct ast_variable *tmp; 03052 struct iax2_user *user=NULL; 03053 03054 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL); 03055 if (!var) 03056 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL); 03057 if (!var && sin) { 03058 char porta[6]; 03059 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 03060 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 03061 if (!var) 03062 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 03063 } 03064 if (!var) { /* Last ditch effort */ 03065 var = ast_load_realtime("iaxusers", "name", username, NULL); 03066 /*!\note 03067 * If this one loaded something, then we need to ensure that the host 03068 * field matched. The only reason why we can't have this as a criteria 03069 * is because we only have the IP address and the host field might be 03070 * set as a name (and the reverse PTR might not match). 03071 */ 03072 if (var) { 03073 for (tmp = var; tmp; tmp = tmp->next) { 03074 if (!strcasecmp(tmp->name, "host")) { 03075 struct ast_hostent ahp; 03076 struct hostent *hp; 03077 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 03078 /* No match */ 03079 ast_variables_destroy(var); 03080 var = NULL; 03081 } 03082 break; 03083 } 03084 } 03085 } 03086 } 03087 if (!var) 03088 return NULL; 03089 03090 tmp = var; 03091 while(tmp) { 03092 /* Make sure it's not a peer only... */ 03093 if (!strcasecmp(tmp->name, "type")) { 03094 if (strcasecmp(tmp->value, "friend") && 03095 strcasecmp(tmp->value, "user")) { 03096 return NULL; 03097 } 03098 } 03099 tmp = tmp->next; 03100 } 03101 03102 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 03103 03104 ast_variables_destroy(var); 03105 03106 if (!user) 03107 return NULL; 03108 03109 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 03110 ast_set_flag(user, IAX_RTCACHEFRIENDS); 03111 ao2_link(users, user); 03112 } else { 03113 ast_set_flag(user, IAX_TEMPONLY); 03114 } 03115 03116 return user; 03117 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 6274 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().
06275 { 06276 char data[80]; 06277 struct in_addr in; 06278 char *c, *d; 06279 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 06280 c = strchr(data, ':'); 06281 if (c) { 06282 *c = '\0'; 06283 c++; 06284 if (inet_aton(data, &in)) { 06285 d = strchr(c, ':'); 06286 if (d) { 06287 *d = '\0'; 06288 d++; 06289 if (option_verbose > 2) 06290 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 06291 ast_inet_ntoa(in), atoi(c), atoi(d)); 06292 iax2_poke_peer(p, 0); 06293 p->expiry = atoi(d); 06294 memset(&p->addr, 0, sizeof(p->addr)); 06295 p->addr.sin_family = AF_INET; 06296 p->addr.sin_addr = in; 06297 p->addr.sin_port = htons(atoi(c)); 06298 if (p->expire > -1) { 06299 if (!ast_sched_del(sched, p->expire)) { 06300 p->expire = -1; 06301 peer_unref(p); 06302 } 06303 } 06304 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06305 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 06306 if (p->expire == -1) 06307 peer_unref(p); 06308 if (iax2_regfunk) 06309 iax2_regfunk(p->name, 1); 06310 register_peer_exten(p, 1); 06311 } 06312 06313 } 06314 } 06315 } 06316 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 6194 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().
06195 { 06196 char multi[256]; 06197 char *stringp, *ext; 06198 if (!ast_strlen_zero(regcontext)) { 06199 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 06200 stringp = multi; 06201 while((ext = strsep(&stringp, "&"))) { 06202 if (onoff) { 06203 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 06204 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 06205 "Noop", ast_strdup(peer->name), ast_free, "IAX2"); 06206 } else 06207 ast_context_remove_extension(regcontext, ext, 1, NULL); 06208 } 06209 } 06210 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 5645 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().
05646 { 05647 char requeststr[256] = ""; 05648 char peer[256] = ""; 05649 char md5secret[256] = ""; 05650 char rsasecret[256] = ""; 05651 char secret[256] = ""; 05652 struct iax2_peer *p = NULL; 05653 struct ast_key *key; 05654 char *keyn; 05655 int x; 05656 int expire = 0; 05657 int res = -1; 05658 05659 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED); 05660 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 05661 if (ies->username) 05662 ast_copy_string(peer, ies->username, sizeof(peer)); 05663 if (ies->password) 05664 ast_copy_string(secret, ies->password, sizeof(secret)); 05665 if (ies->md5_result) 05666 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05667 if (ies->rsa_result) 05668 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05669 if (ies->refresh) 05670 expire = ies->refresh; 05671 05672 if (ast_strlen_zero(peer)) { 05673 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 05674 return -1; 05675 } 05676 05677 /* SLD: first call to lookup peer during registration */ 05678 ast_mutex_unlock(&iaxsl[callno]); 05679 p = find_peer(peer, 1); 05680 ast_mutex_lock(&iaxsl[callno]); 05681 if (!p || !iaxs[callno]) { 05682 if (iaxs[callno]) { 05683 ast_string_field_set(iaxs[callno], secret, "badsecret"); 05684 } 05685 if (authdebug && !p) 05686 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05687 goto return_unref; 05688 } 05689 05690 if (!ast_test_flag(p, IAX_DYNAMIC)) { 05691 if (authdebug) 05692 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05693 goto return_unref; 05694 } 05695 05696 if (!ast_apply_ha(p->ha, sin)) { 05697 if (authdebug) 05698 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05699 goto return_unref; 05700 } 05701 if (!inaddrcmp(&p->addr, sin)) 05702 ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED); 05703 ast_string_field_set(iaxs[callno], secret, p->secret); 05704 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 05705 /* Check secret against what we have on file */ 05706 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05707 if (!ast_strlen_zero(p->inkeys)) { 05708 char tmpkeys[256]; 05709 char *stringp=NULL; 05710 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 05711 stringp=tmpkeys; 05712 keyn = strsep(&stringp, ":"); 05713 while(keyn) { 05714 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05715 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 05716 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05717 break; 05718 } else if (!key) 05719 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 05720 keyn = strsep(&stringp, ":"); 05721 } 05722 if (!keyn) { 05723 if (authdebug) 05724 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 05725 goto return_unref; 05726 } 05727 } else { 05728 if (authdebug) 05729 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 05730 goto return_unref; 05731 } 05732 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05733 struct MD5Context md5; 05734 unsigned char digest[16]; 05735 char *tmppw, *stringp; 05736 05737 tmppw = ast_strdupa(p->secret); 05738 stringp = tmppw; 05739 while((tmppw = strsep(&stringp, ";"))) { 05740 MD5Init(&md5); 05741 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 05742 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05743 MD5Final(digest, &md5); 05744 for (x=0;x<16;x++) 05745 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05746 if (!strcasecmp(requeststr, md5secret)) 05747 break; 05748 } 05749 if (tmppw) { 05750 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05751 } else { 05752 if (authdebug) 05753 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 05754 goto return_unref; 05755 } 05756 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 05757 /* They've provided a plain text password and we support that */ 05758 if (strcmp(secret, p->secret)) { 05759 if (authdebug) 05760 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05761 goto return_unref; 05762 } else 05763 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05764 } else if (!ast_strlen_zero(iaxs[callno]->secret) || !ast_strlen_zero(iaxs[callno]->inkeys)) { 05765 if (authdebug && 05766 ((!ast_strlen_zero(iaxs[callno]->secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) || 05767 (!ast_strlen_zero(iaxs[callno]->inkeys) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)))) { 05768 ast_log(LOG_NOTICE, "Inappropriate authentication received for '%s'\n", p->name); 05769 } /* ELSE this is the first time through and no challenge exists, so it's not quite yet a failure. */ 05770 goto return_unref; 05771 } 05772 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05773 05774 return_unref: 05775 ast_string_field_set(iaxs[callno], peer, peer); 05776 /* Choose lowest expiry number */ 05777 if (expire && (expire < iaxs[callno]->expiry)) 05778 iaxs[callno]->expiry = expire; 05779 05780 res = 0; 05781 05782 if (p) 05783 peer_unref(p); 05784 05785 return res; 05786 }
static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 6453 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().
06454 { 06455 struct iax_ie_data ied; 06456 struct iax2_peer *p; 06457 char challenge[10]; 06458 const char *peer_name; 06459 int sentauthmethod; 06460 06461 peer_name = ast_strdupa(iaxs[callno]->peer); 06462 06463 /* SLD: third call to find_peer in registration */ 06464 ast_mutex_unlock(&iaxsl[callno]); 06465 if ((p = find_peer(peer_name, 1))) { 06466 last_authmethod = p->authmethods; 06467 } 06468 06469 ast_mutex_lock(&iaxsl[callno]); 06470 if (!iaxs[callno]) 06471 goto return_unref; 06472 06473 memset(&ied, 0, sizeof(ied)); 06474 /* The selection of which delayed reject is sent may leak information, 06475 * if it sets a static response. For example, if a host is known to only 06476 * use MD5 authentication, then an RSA response would indicate that the 06477 * peer does not exist, and vice-versa. 06478 * Therefore, we use whatever the last peer used (which may vary over the 06479 * course of a server, which should leak minimal information). */ 06480 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 06481 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod); 06482 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 06483 /* Build the challenge */ 06484 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 06485 ast_string_field_set(iaxs[callno], challenge, challenge); 06486 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 06487 } 06488 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 06489 06490 return_unref: 06491 if (p) { 06492 peer_unref(p); 06493 } 06494 06495 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1; 06496 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 6498 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().
06499 { 06500 struct iax2_registry *reg; 06501 /* Start pessimistic */ 06502 struct iax_ie_data ied; 06503 char peer[256] = ""; 06504 char challenge[256] = ""; 06505 int res; 06506 int authmethods = 0; 06507 if (ies->authmethods) 06508 authmethods = ies->authmethods; 06509 if (ies->username) 06510 ast_copy_string(peer, ies->username, sizeof(peer)); 06511 if (ies->challenge) 06512 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 06513 memset(&ied, 0, sizeof(ied)); 06514 reg = iaxs[callno]->reg; 06515 if (reg) { 06516 if (inaddrcmp(®->addr, sin)) { 06517 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 06518 return -1; 06519 } 06520 if (ast_strlen_zero(reg->secret)) { 06521 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 06522 reg->regstate = REG_STATE_NOAUTH; 06523 return -1; 06524 } 06525 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 06526 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 06527 if (reg->secret[0] == '[') { 06528 char tmpkey[256]; 06529 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 06530 tmpkey[strlen(tmpkey) - 1] = '\0'; 06531 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL); 06532 } else 06533 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL); 06534 if (!res) { 06535 reg->regstate = REG_STATE_AUTHSENT; 06536 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 06537 } else 06538 return -1; 06539 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 06540 } else 06541 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 06542 return -1; 06543 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 4937 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().
04938 { 04939 switch(regstate) { 04940 case REG_STATE_UNREGISTERED: 04941 return "Unregistered"; 04942 case REG_STATE_REGSENT: 04943 return "Request Sent"; 04944 case REG_STATE_AUTHSENT: 04945 return "Auth. Sent"; 04946 case REG_STATE_REGISTERED: 04947 return "Registered"; 04948 case REG_STATE_REJECTED: 04949 return "Rejected"; 04950 case REG_STATE_TIMEOUT: 04951 return "Timeout"; 04952 case REG_STATE_NOAUTH: 04953 return "No Authentication"; 04954 default: 04955 return "Unknown"; 04956 } 04957 }
static int reload | ( | void | ) | [static] |
Definition at line 10464 of file chan_iax2.c.
References reload_config().
10465 { 10466 return reload_config(); 10467 }
static int reload_config | ( | void | ) | [static] |
Definition at line 10438 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().
10439 { 10440 char *config = "iax.conf"; 10441 struct iax2_registry *reg; 10442 10443 if (set_config(config, 1) > 0) { 10444 prune_peers(); 10445 prune_users(); 10446 AST_LIST_LOCK(®istrations); 10447 AST_LIST_TRAVERSE(®istrations, reg, entry) 10448 iax2_do_register(reg); 10449 AST_LIST_UNLOCK(®istrations); 10450 /* Qualify hosts, too */ 10451 poke_all_peers(); 10452 } 10453 reload_firmware(0); 10454 iax_provision_reload(); 10455 10456 return 0; 10457 }
static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 2071 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().
02072 { 02073 struct iax_firmware *cur, *curl, *curp; 02074 DIR *fwd; 02075 struct dirent *de; 02076 char dir[256]; 02077 char fn[256]; 02078 /* Mark all as dead */ 02079 ast_mutex_lock(&waresl.lock); 02080 cur = waresl.wares; 02081 while(cur) { 02082 cur->dead = 1; 02083 cur = cur->next; 02084 } 02085 02086 /* Now that we've freed them, load the new ones */ 02087 if (!unload) { 02088 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR); 02089 fwd = opendir(dir); 02090 if (fwd) { 02091 while((de = readdir(fwd))) { 02092 if (de->d_name[0] != '.') { 02093 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 02094 if (!try_firmware(fn)) { 02095 if (option_verbose > 1) 02096 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name); 02097 } 02098 } 02099 } 02100 closedir(fwd); 02101 } else 02102 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 02103 } 02104 02105 /* Clean up leftovers */ 02106 cur = waresl.wares; 02107 curp = NULL; 02108 while(cur) { 02109 curl = cur; 02110 cur = cur->next; 02111 if (curl->dead) { 02112 if (curp) { 02113 curp->next = cur; 02114 } else { 02115 waresl.wares = cur; 02116 } 02117 destroy_firmware(curl); 02118 } else { 02119 curp = cur; 02120 } 02121 } 02122 ast_mutex_unlock(&waresl.lock); 02123 }
static void remove_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1296 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().
01297 { 01298 if (!pvt->peercallno) { 01299 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01300 return; 01301 } 01302 01303 ao2_unlink(iax_peercallno_pvts, pvt); 01304 }
static void remove_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1277 of file chan_iax2.c.
References ao2_unlink(), ast_log(), iax_transfercallno_pvts, LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by complete_transfer(), and iax2_destroy().
01278 { 01279 if (!pvt->transfercallno) { 01280 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 01281 return; 01282 } 01283 01284 ao2_unlink(iax_transfercallno_pvts, pvt); 01285 }
Definition at line 7002 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().
07003 { 07004 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 07005 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 07006 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 07007 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 07008 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 07009 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 07010 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 07011 }
static void* sched_thread | ( | void * | ignore | ) | [static] |
Definition at line 9238 of file chan_iax2.c.
References ast_cond_timedwait(), ast_cond_wait(), 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().
09239 { 09240 for (;;) { 09241 int ms, count; 09242 struct timespec ts; 09243 09244 pthread_testcancel(); 09245 09246 ast_mutex_lock(&sched_lock); 09247 09248 ms = ast_sched_wait(sched); 09249 09250 if (ms == -1) { 09251 ast_cond_wait(&sched_cond, &sched_lock); 09252 } else { 09253 struct timeval tv; 09254 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(ms, 1000)); 09255 ts.tv_sec = tv.tv_sec; 09256 ts.tv_nsec = tv.tv_usec * 1000; 09257 ast_cond_timedwait(&sched_cond, &sched_lock, &ts); 09258 } 09259 09260 ast_mutex_unlock(&sched_lock); 09261 09262 pthread_testcancel(); 09263 09264 count = ast_sched_runq(sched); 09265 if (option_debug && count >= 20) { 09266 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 09267 } 09268 } 09269 09270 return NULL; 09271 }
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 2779 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().
02780 { 02781 int type, len; 02782 int ret; 02783 int needfree = 0; 02784 struct ast_channel *owner = NULL; 02785 struct ast_channel *bridge = NULL; 02786 02787 /* Attempt to recover wrapped timestamps */ 02788 unwrap_timestamp(fr); 02789 02790 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 02791 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 02792 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 02793 else { 02794 #if 0 02795 if (option_debug) 02796 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 02797 #endif 02798 fr->af.delivery = ast_tv(0,0); 02799 } 02800 02801 type = JB_TYPE_CONTROL; 02802 len = 0; 02803 02804 if(fr->af.frametype == AST_FRAME_VOICE) { 02805 type = JB_TYPE_VOICE; 02806 len = ast_codec_get_samples(&fr->af) / 8; 02807 } else if(fr->af.frametype == AST_FRAME_CNG) { 02808 type = JB_TYPE_SILENCE; 02809 } 02810 02811 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 02812 if (tsout) 02813 *tsout = fr->ts; 02814 __do_deliver(fr); 02815 return -1; 02816 } 02817 02818 if ((owner = iaxs[fr->callno]->owner)) 02819 bridge = ast_bridged_channel(owner); 02820 02821 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 02822 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 02823 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 02824 jb_frame frame; 02825 02826 /* deliver any frames in the jb */ 02827 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 02828 __do_deliver(frame.data); 02829 /* __do_deliver() can make the call disappear */ 02830 if (!iaxs[fr->callno]) 02831 return -1; 02832 } 02833 02834 jb_reset(iaxs[fr->callno]->jb); 02835 02836 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid); 02837 02838 /* deliver this frame now */ 02839 if (tsout) 02840 *tsout = fr->ts; 02841 __do_deliver(fr); 02842 return -1; 02843 } 02844 02845 /* insert into jitterbuffer */ 02846 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 02847 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 02848 calc_rxstamp(iaxs[fr->callno],fr->ts)); 02849 if (ret == JB_DROP) { 02850 needfree++; 02851 } else if (ret == JB_SCHED) { 02852 update_jbsched(iaxs[fr->callno]); 02853 } 02854 if (tsout) 02855 *tsout = fr->ts; 02856 if (needfree) { 02857 /* Free our iax frame */ 02858 iax2_frame_free(fr); 02859 return -1; 02860 } 02861 return 0; 02862 }
static int scheduled_destroy | ( | const void * | vid | ) | [static] |
Definition at line 1387 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().
01388 { 01389 short callno = PTR_TO_CALLNO(vid); 01390 ast_mutex_lock(&iaxsl[callno]); 01391 if (iaxs[callno]) { 01392 if (option_debug) { 01393 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno); 01394 } 01395 iax2_destroy(callno); 01396 } 01397 ast_mutex_unlock(&iaxsl[callno]); 01398 return 0; 01399 }
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 3297 of file chan_iax2.c.
References AST_FRAME_IAX, compress_subclass(), and f.
Referenced by socket_process().
03298 { 03299 struct ast_iax2_full_hdr f = { .scallno = htons(0x8000 | callno), .dcallno = htons(dcallno), 03300 .ts = htonl(ts), .iseqno = seqno, .oseqno = 0, .type = AST_FRAME_IAX, 03301 .csub = compress_subclass(command) }; 03302 03303 return sendto(defaultsockfd, &f, sizeof(f), 0, (struct sockaddr *)sin, sizeof(*sin)); 03304 }
static int send_command | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 5221 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().
05222 { 05223 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 05224 }
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 5240 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().
05241 { 05242 int call_num = i->callno; 05243 /* It is assumed that the callno has already been locked */ 05244 iax2_predestroy(i->callno); 05245 if (!iaxs[call_num]) 05246 return -1; 05247 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 05248 }
static int send_command_immediate | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 5250 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
05251 { 05252 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 05253 }
static int send_command_locked | ( | unsigned short | callno, | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 5226 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().
05227 { 05228 int res; 05229 ast_mutex_lock(&iaxsl[callno]); 05230 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 05231 ast_mutex_unlock(&iaxsl[callno]); 05232 return res; 05233 }
static int send_command_transfer | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | ||||
) | [static] |
Definition at line 5255 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
05256 { 05257 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 05258 }
static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1073 of file chan_iax2.c.
References __send_lagrq(), and schedule_action.
Referenced by __find_callno(), __send_lagrq(), and make_trunk().
01074 { 01075 #ifdef SCHED_MULTITHREADED 01076 if (schedule_action(__send_lagrq, data)) 01077 #endif 01078 __send_lagrq(data); 01079 01080 return 0; 01081 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2196 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().
02197 { 02198 int res; 02199 int callno = f->callno; 02200 02201 /* Don't send if there was an error, but return error instead */ 02202 if (!callno || !iaxs[callno] || iaxs[callno]->error) 02203 return -1; 02204 02205 /* Called with iaxsl held */ 02206 if (option_debug > 2 && iaxdebug) 02207 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)); 02208 if (f->transfer) { 02209 if (iaxdebug) 02210 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 02211 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, 02212 sizeof(iaxs[callno]->transfer)); 02213 } else { 02214 if (iaxdebug) 02215 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 02216 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, 02217 sizeof(iaxs[callno]->addr)); 02218 } 02219 if (res < 0) { 02220 if (option_debug && iaxdebug) 02221 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 02222 handle_error(); 02223 } else 02224 res = 0; 02225 return res; 02226 }
static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 1028 of file chan_iax2.c.
References __send_ping(), and schedule_action.
Referenced by __find_callno(), __send_ping(), and make_trunk().
01029 { 01030 #ifdef SCHED_MULTITHREADED 01031 if (schedule_action(__send_ping, data)) 01032 #endif 01033 __send_ping(data); 01034 01035 return 0; 01036 }
static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [static] |
Definition at line 6680 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().
06681 { 06682 int res = 0; 06683 struct iax_frame *fr; 06684 struct ast_iax2_meta_hdr *meta; 06685 struct ast_iax2_meta_trunk_hdr *mth; 06686 int calls = 0; 06687 06688 /* Point to frame */ 06689 fr = (struct iax_frame *)tpeer->trunkdata; 06690 /* Point to meta data */ 06691 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 06692 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 06693 if (tpeer->trunkdatalen) { 06694 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 06695 meta->zeros = 0; 06696 meta->metacmd = IAX_META_TRUNK; 06697 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 06698 meta->cmddata = IAX_META_TRUNK_MINI; 06699 else 06700 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 06701 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 06702 /* And the rest of the ast_iax2 header */ 06703 fr->direction = DIRECTION_OUTGRESS; 06704 fr->retrans = -1; 06705 fr->transfer = 0; 06706 /* Any appropriate call will do */ 06707 fr->data = fr->afdata; 06708 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 06709 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 06710 calls = tpeer->calls; 06711 #if 0 06712 if (option_debug) 06713 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)); 06714 #endif 06715 /* Reset transmit trunk side data */ 06716 tpeer->trunkdatalen = 0; 06717 tpeer->calls = 0; 06718 } 06719 if (res < 0) 06720 return res; 06721 return calls; 06722 }
static int set_config | ( | char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 10068 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().
10069 { 10070 struct ast_config *cfg, *ucfg; 10071 int capability=iax2_capability; 10072 struct ast_variable *v; 10073 char *cat; 10074 const char *utype; 10075 const char *tosval; 10076 int format; 10077 int portno = IAX_DEFAULT_PORTNO; 10078 int x; 10079 struct iax2_user *user; 10080 struct iax2_peer *peer; 10081 struct ast_netsock *ns; 10082 #if 0 10083 static unsigned short int last_port=0; 10084 #endif 10085 10086 cfg = ast_config_load(config_file); 10087 10088 if (!cfg) { 10089 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 10090 return -1; 10091 } 10092 10093 if (reload) { 10094 set_config_destroy(); 10095 } 10096 10097 /* Reset global codec prefs */ 10098 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 10099 10100 /* Reset Global Flags */ 10101 memset(&globalflags, 0, sizeof(globalflags)); 10102 ast_set_flag(&globalflags, IAX_RTUPDATE); 10103 10104 #ifdef SO_NO_CHECK 10105 nochecksums = 0; 10106 #endif 10107 10108 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 10109 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 10110 10111 maxauthreq = 3; 10112 10113 v = ast_variable_browse(cfg, "general"); 10114 10115 /* Seed initial tos value */ 10116 tosval = ast_variable_retrieve(cfg, "general", "tos"); 10117 if (tosval) { 10118 if (ast_str2tos(tosval, &tos)) 10119 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n"); 10120 } 10121 while(v) { 10122 if (!strcasecmp(v->name, "bindport")){ 10123 if (reload) 10124 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 10125 else 10126 portno = atoi(v->value); 10127 } else if (!strcasecmp(v->name, "pingtime")) 10128 ping_time = atoi(v->value); 10129 else if (!strcasecmp(v->name, "iaxthreadcount")) { 10130 if (reload) { 10131 if (atoi(v->value) != iaxthreadcount) 10132 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 10133 } else { 10134 iaxthreadcount = atoi(v->value); 10135 if (iaxthreadcount < 1) { 10136 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 10137 iaxthreadcount = 1; 10138 } else if (iaxthreadcount > 256) { 10139 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 10140 iaxthreadcount = 256; 10141 } 10142 } 10143 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 10144 if (reload) { 10145 AST_LIST_LOCK(&dynamic_list); 10146 iaxmaxthreadcount = atoi(v->value); 10147 AST_LIST_UNLOCK(&dynamic_list); 10148 } else { 10149 iaxmaxthreadcount = atoi(v->value); 10150 if (iaxmaxthreadcount < 0) { 10151 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 10152 iaxmaxthreadcount = 0; 10153 } else if (iaxmaxthreadcount > 256) { 10154 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 10155 iaxmaxthreadcount = 256; 10156 } 10157 } 10158 } else if (!strcasecmp(v->name, "nochecksums")) { 10159 #ifdef SO_NO_CHECK 10160 if (ast_true(v->value)) 10161 nochecksums = 1; 10162 else 10163 nochecksums = 0; 10164 #else 10165 if (ast_true(v->value)) 10166 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 10167 #endif 10168 } 10169 else if (!strcasecmp(v->name, "maxjitterbuffer")) 10170 maxjitterbuffer = atoi(v->value); 10171 else if (!strcasecmp(v->name, "resyncthreshold")) 10172 resyncthreshold = atoi(v->value); 10173 else if (!strcasecmp(v->name, "maxjitterinterps")) 10174 maxjitterinterps = atoi(v->value); 10175 else if (!strcasecmp(v->name, "lagrqtime")) 10176 lagrq_time = atoi(v->value); 10177 else if (!strcasecmp(v->name, "maxregexpire")) 10178 max_reg_expire = atoi(v->value); 10179 else if (!strcasecmp(v->name, "minregexpire")) 10180 min_reg_expire = atoi(v->value); 10181 else if (!strcasecmp(v->name, "bindaddr")) { 10182 if (reload) { 10183 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 10184 } else { 10185 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) { 10186 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 10187 } else { 10188 if (option_verbose > 1) { 10189 if (strchr(v->value, ':')) 10190 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value); 10191 else 10192 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno); 10193 } 10194 if (defaultsockfd < 0) 10195 defaultsockfd = ast_netsock_sockfd(ns); 10196 ast_netsock_unref(ns); 10197 } 10198 } 10199 } else if (!strcasecmp(v->name, "authdebug")) 10200 authdebug = ast_true(v->value); 10201 else if (!strcasecmp(v->name, "encryption")) 10202 iax2_encryption = get_encrypt_methods(v->value); 10203 else if (!strcasecmp(v->name, "notransfer")) { 10204 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 10205 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 10206 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER); 10207 } else if (!strcasecmp(v->name, "transfer")) { 10208 if (!strcasecmp(v->value, "mediaonly")) { 10209 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 10210 } else if (ast_true(v->value)) { 10211 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 10212 } else 10213 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 10214 } else if (!strcasecmp(v->name, "codecpriority")) { 10215 if(!strcasecmp(v->value, "caller")) 10216 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 10217 else if(!strcasecmp(v->value, "disabled")) 10218 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 10219 else if(!strcasecmp(v->value, "reqonly")) { 10220 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 10221 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 10222 } 10223 } else if (!strcasecmp(v->name, "jitterbuffer")) 10224 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 10225 else if (!strcasecmp(v->name, "forcejitterbuffer")) 10226 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 10227 else if (!strcasecmp(v->name, "delayreject")) 10228 delayreject = ast_true(v->value); 10229 else if (!strcasecmp(v->name, "allowfwdownload")) 10230 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 10231 else if (!strcasecmp(v->name, "rtcachefriends")) 10232 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 10233 else if (!strcasecmp(v->name, "rtignoreregexpire")) 10234 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 10235 else if (!strcasecmp(v->name, "rtupdate")) 10236 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 10237 else if (!strcasecmp(v->name, "trunktimestamps")) 10238 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 10239 else if (!strcasecmp(v->name, "rtautoclear")) { 10240 int i = atoi(v->value); 10241 if(i > 0) 10242 global_rtautoclear = i; 10243 else 10244 i = 0; 10245 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 10246 } else if (!strcasecmp(v->name, "trunkfreq")) { 10247 trunkfreq = atoi(v->value); 10248 if (trunkfreq < 10) 10249 trunkfreq = 10; 10250 } else if (!strcasecmp(v->name, "autokill")) { 10251 if (sscanf(v->value, "%d", &x) == 1) { 10252 if (x >= 0) 10253 autokill = x; 10254 else 10255 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 10256 } else if (ast_true(v->value)) { 10257 autokill = DEFAULT_MAXMS; 10258 } else { 10259 autokill = 0; 10260 } 10261 } else if (!strcasecmp(v->name, "bandwidth")) { 10262 if (!strcasecmp(v->value, "low")) { 10263 capability = IAX_CAPABILITY_LOWBANDWIDTH; 10264 } else if (!strcasecmp(v->value, "medium")) { 10265 capability = IAX_CAPABILITY_MEDBANDWIDTH; 10266 } else if (!strcasecmp(v->value, "high")) { 10267 capability = IAX_CAPABILITY_FULLBANDWIDTH; 10268 } else 10269 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 10270 } else if (!strcasecmp(v->name, "allow")) { 10271 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 10272 } else if (!strcasecmp(v->name, "disallow")) { 10273 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 10274 } else if (!strcasecmp(v->name, "register")) { 10275 iax2_register(v->value, v->lineno); 10276 } else if (!strcasecmp(v->name, "iaxcompat")) { 10277 iaxcompat = ast_true(v->value); 10278 } else if (!strcasecmp(v->name, "regcontext")) { 10279 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 10280 /* Create context if it doesn't exist already */ 10281 if (!ast_context_find(regcontext)) 10282 ast_context_create(NULL, regcontext, "IAX2"); 10283 } else if (!strcasecmp(v->name, "tos")) { 10284 if (ast_str2tos(v->value, &tos)) 10285 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno); 10286 } else if (!strcasecmp(v->name, "accountcode")) { 10287 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 10288 } else if (!strcasecmp(v->name, "mohinterpret")) { 10289 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret)); 10290 } else if (!strcasecmp(v->name, "mohsuggest")) { 10291 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest)); 10292 } else if (!strcasecmp(v->name, "amaflags")) { 10293 format = ast_cdr_amaflags2int(v->value); 10294 if (format < 0) { 10295 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 10296 } else { 10297 amaflags = format; 10298 } 10299 } else if (!strcasecmp(v->name, "language")) { 10300 ast_copy_string(language, v->value, sizeof(language)); 10301 } else if (!strcasecmp(v->name, "maxauthreq")) { 10302 maxauthreq = atoi(v->value); 10303 if (maxauthreq < 0) 10304 maxauthreq = 0; 10305 } else if (!strcasecmp(v->name, "adsi")) { 10306 adsi = ast_true(v->value); 10307 } /*else if (strcasecmp(v->name,"type")) */ 10308 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 10309 v = v->next; 10310 } 10311 10312 if (defaultsockfd < 0) { 10313 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) { 10314 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 10315 } else { 10316 if (option_verbose > 1) 10317 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 10318 defaultsockfd = ast_netsock_sockfd(ns); 10319 ast_netsock_unref(ns); 10320 } 10321 } 10322 if (reload) { 10323 ast_netsock_release(outsock); 10324 outsock = ast_netsock_list_alloc(); 10325 if (!outsock) { 10326 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 10327 return -1; 10328 } 10329 ast_netsock_init(outsock); 10330 } 10331 10332 if (min_reg_expire > max_reg_expire) { 10333 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 10334 min_reg_expire, max_reg_expire, max_reg_expire); 10335 min_reg_expire = max_reg_expire; 10336 } 10337 iax2_capability = capability; 10338 10339 ucfg = ast_config_load("users.conf"); 10340 if (ucfg) { 10341 struct ast_variable *gen; 10342 int genhasiax; 10343 int genregisteriax; 10344 const char *hasiax, *registeriax; 10345 10346 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 10347 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 10348 gen = ast_variable_browse(ucfg, "general"); 10349 cat = ast_category_browse(ucfg, NULL); 10350 while (cat) { 10351 if (strcasecmp(cat, "general")) { 10352 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 10353 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 10354 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 10355 /* Start with general parameters, then specific parameters, user and peer */ 10356 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 10357 if (user) { 10358 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10359 user = user_unref(user); 10360 } 10361 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 10362 if (peer) { 10363 if (ast_test_flag(peer, IAX_DYNAMIC)) 10364 reg_source_db(peer); 10365 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10366 peer = peer_unref(peer); 10367 } 10368 } 10369 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 10370 char tmp[256]; 10371 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 10372 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 10373 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 10374 if (!host) 10375 host = ast_variable_retrieve(ucfg, "general", "host"); 10376 if (!username) 10377 username = ast_variable_retrieve(ucfg, "general", "username"); 10378 if (!secret) 10379 secret = ast_variable_retrieve(ucfg, "general", "secret"); 10380 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 10381 if (!ast_strlen_zero(secret)) 10382 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 10383 else 10384 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 10385 iax2_register(tmp, 0); 10386 } 10387 } 10388 } 10389 cat = ast_category_browse(ucfg, cat); 10390 } 10391 ast_config_destroy(ucfg); 10392 } 10393 10394 cat = ast_category_browse(cfg, NULL); 10395 while(cat) { 10396 if (strcasecmp(cat, "general")) { 10397 utype = ast_variable_retrieve(cfg, cat, "type"); 10398 if (utype) { 10399 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 10400 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 10401 if (user) { 10402 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10403 user = user_unref(user); 10404 } 10405 } 10406 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 10407 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 10408 if (peer) { 10409 if (ast_test_flag(peer, IAX_DYNAMIC)) 10410 reg_source_db(peer); 10411 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10412 peer = peer_unref(peer); 10413 } 10414 } else if (strcasecmp(utype, "user")) { 10415 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 10416 } 10417 } else 10418 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 10419 } 10420 cat = ast_category_browse(cfg, cat); 10421 } 10422 ast_config_destroy(cfg); 10423 set_timing(); 10424 return 1; 10425 }
static void set_config_destroy | ( | void | ) | [static] |
Definition at line 10052 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().
10053 { 10054 strcpy(accountcode, ""); 10055 strcpy(language, ""); 10056 strcpy(mohinterpret, "default"); 10057 strcpy(mohsuggest, ""); 10058 amaflags = 0; 10059 delayreject = 0; 10060 ast_clear_flag((&globalflags), IAX_NOTRANSFER); 10061 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 10062 ast_clear_flag((&globalflags), IAX_USEJITTERBUF); 10063 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF); 10064 delete_users(); 10065 }
static void set_timing | ( | void | ) | [static] |
Definition at line 10037 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by set_config().
10038 { 10039 #ifdef HAVE_DAHDI 10040 int bs = trunkfreq * 8; 10041 if (timingfd > -1) { 10042 if ( 10043 #ifdef DAHDI_TIMERACK 10044 ioctl(timingfd, DAHDI_TIMERCONFIG, &bs) && 10045 #endif 10046 ioctl(timingfd, DAHDI_SET_BLOCKSIZE, &bs)) 10047 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n"); 10048 } 10049 #endif 10050 }
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_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 7154 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().
07155 { 07156 struct sockaddr_in sin; 07157 int res; 07158 int updatehistory=1; 07159 int new = NEW_PREVENT; 07160 void *ptr; 07161 int dcallno = 0; 07162 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 07163 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 07164 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 07165 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 07166 struct ast_iax2_meta_trunk_hdr *mth; 07167 struct ast_iax2_meta_trunk_entry *mte; 07168 struct ast_iax2_meta_trunk_mini *mtm; 07169 struct iax_frame *fr; 07170 struct iax_frame *cur; 07171 struct ast_frame f = { 0, }; 07172 struct ast_channel *c; 07173 struct iax2_dpcache *dp; 07174 struct iax2_peer *peer; 07175 struct iax2_trunk_peer *tpeer; 07176 struct timeval rxtrunktime; 07177 struct iax_ies ies; 07178 struct iax_ie_data ied0, ied1; 07179 int format; 07180 int fd; 07181 int exists; 07182 int minivid = 0; 07183 unsigned int ts; 07184 char empty[32]=""; /* Safety measure */ 07185 struct iax_frame *duped_fr; 07186 char host_pref_buf[128]; 07187 char caller_pref_buf[128]; 07188 struct ast_codec_pref pref; 07189 char *using_prefs = "mine"; 07190 07191 /* allocate an iax_frame with 4096 bytes of data buffer */ 07192 fr = alloca(sizeof(*fr) + 4096); 07193 memset(fr, 0, sizeof(*fr)); 07194 fr->afdatalen = 4096; /* From alloca() above */ 07195 07196 /* Copy frequently used parameters to the stack */ 07197 res = thread->buf_len; 07198 fd = thread->iofd; 07199 memcpy(&sin, &thread->iosin, sizeof(sin)); 07200 07201 if (res < sizeof(*mh)) { 07202 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh)); 07203 return 1; 07204 } 07205 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 07206 if (res < sizeof(*vh)) { 07207 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)); 07208 return 1; 07209 } 07210 07211 /* This is a video frame, get call number */ 07212 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 07213 minivid = 1; 07214 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) { 07215 unsigned char metatype; 07216 07217 if (res < sizeof(*meta)) { 07218 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)); 07219 return 1; 07220 } 07221 07222 /* This is a meta header */ 07223 switch(meta->metacmd) { 07224 case IAX_META_TRUNK: 07225 if (res < (sizeof(*meta) + sizeof(*mth))) { 07226 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res, 07227 sizeof(*meta) + sizeof(*mth)); 07228 return 1; 07229 } 07230 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 07231 ts = ntohl(mth->ts); 07232 metatype = meta->cmddata; 07233 res -= (sizeof(*meta) + sizeof(*mth)); 07234 ptr = mth->data; 07235 tpeer = find_tpeer(&sin, fd); 07236 if (!tpeer) { 07237 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)); 07238 return 1; 07239 } 07240 tpeer->trunkact = ast_tvnow(); 07241 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 07242 tpeer->rxtrunktime = tpeer->trunkact; 07243 rxtrunktime = tpeer->rxtrunktime; 07244 ast_mutex_unlock(&tpeer->lock); 07245 while(res >= sizeof(*mte)) { 07246 /* Process channels */ 07247 unsigned short callno, trunked_ts, len; 07248 07249 if (metatype == IAX_META_TRUNK_MINI) { 07250 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 07251 ptr += sizeof(*mtm); 07252 res -= sizeof(*mtm); 07253 len = ntohs(mtm->len); 07254 callno = ntohs(mtm->mini.callno); 07255 trunked_ts = ntohs(mtm->mini.ts); 07256 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 07257 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 07258 ptr += sizeof(*mte); 07259 res -= sizeof(*mte); 07260 len = ntohs(mte->len); 07261 callno = ntohs(mte->callno); 07262 trunked_ts = 0; 07263 } else { 07264 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 07265 break; 07266 } 07267 /* Stop if we don't have enough data */ 07268 if (len > res) 07269 break; 07270 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0); 07271 if (fr->callno) { 07272 /* If it's a valid call, deliver the contents. If not, we 07273 drop it, since we don't have a scallno to use for an INVAL */ 07274 /* Process as a mini frame */ 07275 memset(&f, 0, sizeof(f)); 07276 f.frametype = AST_FRAME_VOICE; 07277 if (iaxs[fr->callno]) { 07278 if (iaxs[fr->callno]->voiceformat > 0) { 07279 f.subclass = iaxs[fr->callno]->voiceformat; 07280 f.datalen = len; 07281 if (f.datalen >= 0) { 07282 if (f.datalen) 07283 f.data = ptr; 07284 if(trunked_ts) { 07285 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 07286 } else 07287 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 07288 /* Don't pass any packets until we're started */ 07289 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07290 /* Common things */ 07291 f.src = "IAX2"; 07292 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 07293 f.samples = ast_codec_get_samples(&f); 07294 iax_frame_wrap(fr, &f); 07295 duped_fr = iaxfrdup2(fr); 07296 if (duped_fr) { 07297 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); 07298 } 07299 /* It is possible for the pvt structure to go away after we call schedule_delivery */ 07300 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 07301 iaxs[fr->callno]->last = fr->ts; 07302 #if 1 07303 if (option_debug && iaxdebug) 07304 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07305 #endif 07306 } 07307 } 07308 } else { 07309 ast_log(LOG_WARNING, "Datalen < 0?\n"); 07310 } 07311 } else { 07312 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n"); 07313 iax2_vnak(fr->callno); 07314 } 07315 } 07316 ast_mutex_unlock(&iaxsl[fr->callno]); 07317 } 07318 ptr += len; 07319 res -= len; 07320 } 07321 07322 } 07323 return 1; 07324 } 07325 07326 #ifdef DEBUG_SUPPORT 07327 if (iaxdebug && (res >= sizeof(*fh))) 07328 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 07329 #endif 07330 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07331 if (res < sizeof(*fh)) { 07332 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)); 07333 return 1; 07334 } 07335 07336 /* Get the destination call number */ 07337 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 07338 /* Retrieve the type and subclass */ 07339 f.frametype = fh->type; 07340 if (f.frametype == AST_FRAME_VIDEO) { 07341 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 07342 } else { 07343 f.subclass = uncompress_subclass(fh->csub); 07344 } 07345 07346 /* Deal with POKE/PONG without allocating a callno */ 07347 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) { 07348 /* Reply back with a PONG, but don't care about the result. */ 07349 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohs(fh->ts), fh->iseqno + 1); 07350 return 1; 07351 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) { 07352 /* Ignore */ 07353 return 1; 07354 } 07355 07356 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) || 07357 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) || 07358 (f.subclass == IAX_COMMAND_REGREL))) 07359 new = NEW_ALLOW; 07360 } else { 07361 /* Don't know anything about it yet */ 07362 f.frametype = AST_FRAME_NULL; 07363 f.subclass = 0; 07364 } 07365 07366 if (!fr->callno) { 07367 int check_dcallno = 0; 07368 07369 /* 07370 * We enforce accurate destination call numbers for all full frames except 07371 * LAGRQ and PING commands. This is because older versions of Asterisk 07372 * schedule these commands to get sent very quickly, and they will sometimes 07373 * be sent before they receive the first frame from the other side. When 07374 * that happens, it doesn't contain the destination call number. However, 07375 * not checking it for these frames is safe. 07376 * 07377 * Discussed in the following thread: 07378 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 07379 */ 07380 07381 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07382 check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1; 07383 } 07384 07385 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno); 07386 } 07387 07388 if (fr->callno > 0) 07389 ast_mutex_lock(&iaxsl[fr->callno]); 07390 07391 if (!fr->callno || !iaxs[fr->callno]) { 07392 /* A call arrived for a nonexistent destination. Unless it's an "inval" 07393 frame, reply with an inval */ 07394 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07395 /* We can only raw hangup control frames */ 07396 if (((f.subclass != IAX_COMMAND_INVAL) && 07397 (f.subclass != IAX_COMMAND_TXCNT) && 07398 (f.subclass != IAX_COMMAND_TXACC) && 07399 (f.subclass != IAX_COMMAND_FWDOWNL))|| 07400 (f.frametype != AST_FRAME_IAX)) 07401 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 07402 fd); 07403 } 07404 if (fr->callno > 0) 07405 ast_mutex_unlock(&iaxsl[fr->callno]); 07406 return 1; 07407 } 07408 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { 07409 if (decrypt_frame(fr->callno, fh, &f, &res)) { 07410 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 07411 ast_mutex_unlock(&iaxsl[fr->callno]); 07412 return 1; 07413 } 07414 #ifdef DEBUG_SUPPORT 07415 else if (iaxdebug) 07416 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 07417 #endif 07418 } 07419 07420 /* count this frame */ 07421 iaxs[fr->callno]->frames_received++; 07422 07423 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 07424 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 07425 f.subclass != IAX_COMMAND_TXACC) { /* for attended transfer */ 07426 unsigned short new_peercallno; 07427 07428 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 07429 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 07430 if (iaxs[fr->callno]->peercallno) { 07431 remove_by_peercallno(iaxs[fr->callno]); 07432 } 07433 iaxs[fr->callno]->peercallno = new_peercallno; 07434 store_by_peercallno(iaxs[fr->callno]); 07435 } 07436 } 07437 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07438 if (option_debug && iaxdebug) 07439 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 07440 /* Check if it's out of order (and not an ACK or INVAL) */ 07441 fr->oseqno = fh->oseqno; 07442 fr->iseqno = fh->iseqno; 07443 fr->ts = ntohl(fh->ts); 07444 #ifdef IAXTESTS 07445 if (test_resync) { 07446 if (option_debug) 07447 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 07448 fr->ts += test_resync; 07449 } 07450 #endif /* IAXTESTS */ 07451 #if 0 07452 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 07453 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 07454 (f.subclass == IAX_COMMAND_NEW || 07455 f.subclass == IAX_COMMAND_AUTHREQ || 07456 f.subclass == IAX_COMMAND_ACCEPT || 07457 f.subclass == IAX_COMMAND_REJECT)) ) ) 07458 #endif 07459 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 07460 updatehistory = 0; 07461 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 07462 (iaxs[fr->callno]->iseqno || 07463 ((f.subclass != IAX_COMMAND_TXCNT) && 07464 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 07465 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 07466 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 07467 (f.subclass != IAX_COMMAND_TXACC)) || 07468 (f.frametype != AST_FRAME_IAX))) { 07469 if ( 07470 ((f.subclass != IAX_COMMAND_ACK) && 07471 (f.subclass != IAX_COMMAND_INVAL) && 07472 (f.subclass != IAX_COMMAND_TXCNT) && 07473 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 07474 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 07475 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 07476 (f.subclass != IAX_COMMAND_TXACC) && 07477 (f.subclass != IAX_COMMAND_VNAK)) || 07478 (f.frametype != AST_FRAME_IAX)) { 07479 /* If it's not an ACK packet, it's out of order. */ 07480 if (option_debug) 07481 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 07482 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); 07483 /* Check to see if we need to request retransmission, 07484 * and take sequence number wraparound into account */ 07485 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 07486 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 07487 if ((f.frametype != AST_FRAME_IAX) || 07488 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 07489 if (option_debug) 07490 ast_log(LOG_DEBUG, "Acking anyway\n"); 07491 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 07492 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 07493 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07494 } 07495 } else { 07496 /* Send a VNAK requesting retransmission */ 07497 iax2_vnak(fr->callno); 07498 } 07499 ast_mutex_unlock(&iaxsl[fr->callno]); 07500 return 1; 07501 } 07502 } else { 07503 /* Increment unless it's an ACK or VNAK */ 07504 if (((f.subclass != IAX_COMMAND_ACK) && 07505 (f.subclass != IAX_COMMAND_INVAL) && 07506 (f.subclass != IAX_COMMAND_TXCNT) && 07507 (f.subclass != IAX_COMMAND_TXACC) && 07508 (f.subclass != IAX_COMMAND_VNAK)) || 07509 (f.frametype != AST_FRAME_IAX)) 07510 iaxs[fr->callno]->iseqno++; 07511 } 07512 /* A full frame */ 07513 if (res < sizeof(*fh)) { 07514 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh)); 07515 ast_mutex_unlock(&iaxsl[fr->callno]); 07516 return 1; 07517 } 07518 /* Ensure text frames are NULL-terminated */ 07519 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 07520 if (res < thread->buf_size) 07521 thread->buf[res++] = '\0'; 07522 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 07523 thread->buf[res - 1] = '\0'; 07524 } 07525 f.datalen = res - sizeof(*fh); 07526 07527 /* Handle implicit ACKing unless this is an INVAL, and only if this is 07528 from the real peer, not the transfer peer */ 07529 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07530 ((f.subclass != IAX_COMMAND_INVAL) || 07531 (f.frametype != AST_FRAME_IAX))) { 07532 unsigned char x; 07533 int call_to_destroy; 07534 /* XXX This code is not very efficient. Surely there is a better way which still 07535 properly handles boundary conditions? XXX */ 07536 /* First we have to qualify that the ACKed value is within our window */ 07537 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++) 07538 if (fr->iseqno == x) 07539 break; 07540 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 07541 /* The acknowledgement is within our window. Time to acknowledge everything 07542 that it says to */ 07543 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 07544 /* Ack the packet with the given timestamp */ 07545 if (option_debug && iaxdebug) 07546 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x); 07547 call_to_destroy = 0; 07548 AST_LIST_LOCK(&iaxq.queue); 07549 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07550 /* If it's our call, and our timestamp, mark -1 retries */ 07551 if ((fr->callno == cur->callno) && (x == cur->oseqno)) { 07552 cur->retries = -1; 07553 /* Destroy call if this is the end */ 07554 if (cur->final) 07555 call_to_destroy = fr->callno; 07556 } 07557 } 07558 AST_LIST_UNLOCK(&iaxq.queue); 07559 if (call_to_destroy) { 07560 if (iaxdebug && option_debug) 07561 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy); 07562 ast_mutex_lock(&iaxsl[call_to_destroy]); 07563 iax2_destroy(call_to_destroy); 07564 ast_mutex_unlock(&iaxsl[call_to_destroy]); 07565 } 07566 } 07567 /* Note how much we've received acknowledgement for */ 07568 if (iaxs[fr->callno]) 07569 iaxs[fr->callno]->rseqno = fr->iseqno; 07570 else { 07571 /* Stop processing now */ 07572 ast_mutex_unlock(&iaxsl[fr->callno]); 07573 return 1; 07574 } 07575 } else if (option_debug) 07576 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 07577 } 07578 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07579 ((f.frametype != AST_FRAME_IAX) || 07580 ((f.subclass != IAX_COMMAND_TXACC) && 07581 (f.subclass != IAX_COMMAND_TXCNT)))) { 07582 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 07583 ast_mutex_unlock(&iaxsl[fr->callno]); 07584 return 1; 07585 } 07586 07587 if (f.datalen) { 07588 if (f.frametype == AST_FRAME_IAX) { 07589 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) { 07590 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 07591 ast_mutex_unlock(&iaxsl[fr->callno]); 07592 return 1; 07593 } 07594 f.data = NULL; 07595 f.datalen = 0; 07596 } else 07597 f.data = thread->buf + sizeof(*fh); 07598 } else { 07599 if (f.frametype == AST_FRAME_IAX) 07600 f.data = NULL; 07601 else 07602 f.data = empty; 07603 memset(&ies, 0, sizeof(ies)); 07604 } 07605 07606 /* when we receive the first full frame for a new incoming channel, 07607 it is safe to start the PBX on the channel because we have now 07608 completed a 3-way handshake with the peer */ 07609 if ((f.frametype == AST_FRAME_VOICE) || 07610 (f.frametype == AST_FRAME_VIDEO) || 07611 (f.frametype == AST_FRAME_IAX)) { 07612 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 07613 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07614 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) { 07615 ast_mutex_unlock(&iaxsl[fr->callno]); 07616 return 1; 07617 } 07618 } 07619 } 07620 07621 if (f.frametype == AST_FRAME_VOICE) { 07622 if (f.subclass != iaxs[fr->callno]->voiceformat) { 07623 iaxs[fr->callno]->voiceformat = f.subclass; 07624 if (option_debug) 07625 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass); 07626 if (iaxs[fr->callno]->owner) { 07627 int orignative; 07628 retryowner: 07629 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07630 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 07631 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner; 07632 } 07633 if (iaxs[fr->callno]) { 07634 if (iaxs[fr->callno]->owner) { 07635 orignative = iaxs[fr->callno]->owner->nativeformats; 07636 iaxs[fr->callno]->owner->nativeformats = f.subclass; 07637 if (iaxs[fr->callno]->owner->readformat) 07638 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07639 iaxs[fr->callno]->owner->nativeformats = orignative; 07640 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07641 } 07642 } else { 07643 if (option_debug) 07644 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); 07645 ast_mutex_unlock(&iaxsl[fr->callno]); 07646 return 1; 07647 } 07648 } 07649 } 07650 } 07651 if (f.frametype == AST_FRAME_VIDEO) { 07652 if (f.subclass != iaxs[fr->callno]->videoformat) { 07653 if (option_debug) 07654 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 07655 iaxs[fr->callno]->videoformat = f.subclass & ~0x1; 07656 } 07657 } 07658 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) { 07659 if (f.subclass == AST_CONTROL_BUSY) { 07660 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY; 07661 } else if (f.subclass == AST_CONTROL_CONGESTION) { 07662 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION; 07663 } 07664 } 07665 if (f.frametype == AST_FRAME_IAX) { 07666 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid); 07667 /* Handle the IAX pseudo frame itself */ 07668 if (option_debug && iaxdebug) 07669 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); 07670 07671 /* Update last ts unless the frame's timestamp originated with us. */ 07672 if (iaxs[fr->callno]->last < fr->ts && 07673 f.subclass != IAX_COMMAND_ACK && 07674 f.subclass != IAX_COMMAND_PONG && 07675 f.subclass != IAX_COMMAND_LAGRP) { 07676 iaxs[fr->callno]->last = fr->ts; 07677 if (option_debug && iaxdebug) 07678 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07679 } 07680 07681 switch(f.subclass) { 07682 case IAX_COMMAND_ACK: 07683 /* Do nothing */ 07684 break; 07685 case IAX_COMMAND_QUELCH: 07686 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07687 /* Generate Manager Hold event, if necessary*/ 07688 if (iaxs[fr->callno]->owner) { 07689 manager_event(EVENT_FLAG_CALL, "Hold", 07690 "Channel: %s\r\n" 07691 "Uniqueid: %s\r\n", 07692 iaxs[fr->callno]->owner->name, 07693 iaxs[fr->callno]->owner->uniqueid); 07694 } 07695 07696 ast_set_flag(iaxs[fr->callno], IAX_QUELCH); 07697 if (ies.musiconhold) { 07698 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07699 const char *mohsuggest = iaxs[fr->callno]->mohsuggest; 07700 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 07701 S_OR(mohsuggest, NULL), 07702 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0); 07703 if (!iaxs[fr->callno]) { 07704 ast_mutex_unlock(&iaxsl[fr->callno]); 07705 return 1; 07706 } 07707 } 07708 } 07709 } 07710 break; 07711 case IAX_COMMAND_UNQUELCH: 07712 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07713 /* Generate Manager Unhold event, if necessary*/ 07714 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { 07715 manager_event(EVENT_FLAG_CALL, "Unhold", 07716 "Channel: %s\r\n" 07717 "Uniqueid: %s\r\n", 07718 iaxs[fr->callno]->owner->name, 07719 iaxs[fr->callno]->owner->uniqueid); 07720 } 07721 07722 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); 07723 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07724 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 07725 if (!iaxs[fr->callno]) { 07726 ast_mutex_unlock(&iaxsl[fr->callno]); 07727 return 1; 07728 } 07729 } 07730 } 07731 break; 07732 case IAX_COMMAND_TXACC: 07733 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 07734 /* Ack the packet with the given timestamp */ 07735 AST_LIST_LOCK(&iaxq.queue); 07736 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07737 /* Cancel any outstanding txcnt's */ 07738 if ((fr->callno == cur->callno) && (cur->transfer)) 07739 cur->retries = -1; 07740 } 07741 AST_LIST_UNLOCK(&iaxq.queue); 07742 memset(&ied1, 0, sizeof(ied1)); 07743 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 07744 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 07745 iaxs[fr->callno]->transferring = TRANSFER_READY; 07746 } 07747 break; 07748 case IAX_COMMAND_NEW: 07749 /* Ignore if it's already up */ 07750 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 07751 break; 07752 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 07753 ast_mutex_unlock(&iaxsl[fr->callno]); 07754 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 07755 ast_mutex_lock(&iaxsl[fr->callno]); 07756 if (!iaxs[fr->callno]) { 07757 ast_mutex_unlock(&iaxsl[fr->callno]); 07758 return 1; 07759 } 07760 } 07761 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 07762 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { 07763 int new_callno; 07764 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 07765 fr->callno = new_callno; 07766 } 07767 /* For security, always ack immediately */ 07768 if (delayreject) 07769 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07770 if (check_access(fr->callno, &sin, &ies)) { 07771 /* They're not allowed on */ 07772 auth_fail(fr->callno, IAX_COMMAND_REJECT); 07773 if (authdebug) 07774 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); 07775 break; 07776 } 07777 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 07778 const char *context, *exten, *cid_num; 07779 07780 context = ast_strdupa(iaxs[fr->callno]->context); 07781 exten = ast_strdupa(iaxs[fr->callno]->exten); 07782 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 07783 07784 /* This might re-enter the IAX code and need the lock */ 07785 ast_mutex_unlock(&iaxsl[fr->callno]); 07786 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 07787 ast_mutex_lock(&iaxsl[fr->callno]); 07788 07789 if (!iaxs[fr->callno]) { 07790 ast_mutex_unlock(&iaxsl[fr->callno]); 07791 return 1; 07792 } 07793 } else 07794 exists = 0; 07795 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 07796 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 07797 memset(&ied0, 0, sizeof(ied0)); 07798 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07799 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07800 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07801 if (!iaxs[fr->callno]) { 07802 ast_mutex_unlock(&iaxsl[fr->callno]); 07803 return 1; 07804 } 07805 if (authdebug) 07806 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); 07807 } else { 07808 /* Select an appropriate format */ 07809 07810 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07811 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07812 using_prefs = "reqonly"; 07813 } else { 07814 using_prefs = "disabled"; 07815 } 07816 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 07817 memset(&pref, 0, sizeof(pref)); 07818 strcpy(caller_pref_buf, "disabled"); 07819 strcpy(host_pref_buf, "disabled"); 07820 } else { 07821 using_prefs = "mine"; 07822 /* If the information elements are in here... use them */ 07823 if (ies.codec_prefs) 07824 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 07825 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07826 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 07827 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07828 pref = iaxs[fr->callno]->rprefs; 07829 using_prefs = "caller"; 07830 } else { 07831 pref = iaxs[fr->callno]->prefs; 07832 } 07833 } else 07834 pref = iaxs[fr->callno]->prefs; 07835 07836 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 07837 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 07838 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 07839 } 07840 if (!format) { 07841 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07842 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 07843 if (!format) { 07844 memset(&ied0, 0, sizeof(ied0)); 07845 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07846 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07847 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07848 if (!iaxs[fr->callno]) { 07849 ast_mutex_unlock(&iaxsl[fr->callno]); 07850 return 1; 07851 } 07852 if (authdebug) { 07853 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07854 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); 07855 else 07856 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); 07857 } 07858 } else { 07859 /* Pick one... */ 07860 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07861 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 07862 format = 0; 07863 } else { 07864 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07865 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 07866 memset(&pref, 0, sizeof(pref)); 07867 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07868 strcpy(caller_pref_buf,"disabled"); 07869 strcpy(host_pref_buf,"disabled"); 07870 } else { 07871 using_prefs = "mine"; 07872 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07873 /* Do the opposite of what we tried above. */ 07874 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07875 pref = iaxs[fr->callno]->prefs; 07876 } else { 07877 pref = iaxs[fr->callno]->rprefs; 07878 using_prefs = "caller"; 07879 } 07880 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 07881 07882 } else /* if no codec_prefs IE do it the old way */ 07883 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07884 } 07885 } 07886 07887 if (!format) { 07888 memset(&ied0, 0, sizeof(ied0)); 07889 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07890 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07891 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07892 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07893 if (!iaxs[fr->callno]) { 07894 ast_mutex_unlock(&iaxsl[fr->callno]); 07895 return 1; 07896 } 07897 if (authdebug) 07898 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); 07899 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07900 break; 07901 } 07902 } 07903 } 07904 if (format) { 07905 /* No authentication required, let them in */ 07906 memset(&ied1, 0, sizeof(ied1)); 07907 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 07908 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 07909 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 07910 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07911 if (option_verbose > 2) 07912 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" 07913 "%srequested format = %s,\n" 07914 "%srequested prefs = %s,\n" 07915 "%sactual format = %s,\n" 07916 "%shost prefs = %s,\n" 07917 "%spriority = %s\n", 07918 ast_inet_ntoa(sin.sin_addr), 07919 VERBOSE_PREFIX_4, 07920 ast_getformatname(iaxs[fr->callno]->peerformat), 07921 VERBOSE_PREFIX_4, 07922 caller_pref_buf, 07923 VERBOSE_PREFIX_4, 07924 ast_getformatname(format), 07925 VERBOSE_PREFIX_4, 07926 host_pref_buf, 07927 VERBOSE_PREFIX_4, 07928 using_prefs); 07929 07930 iaxs[fr->callno]->chosenformat = format; 07931 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07932 } else { 07933 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07934 /* If this is a TBD call, we're ready but now what... */ 07935 if (option_verbose > 2) 07936 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 07937 } 07938 } 07939 } 07940 break; 07941 } 07942 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 07943 merge_encryption(iaxs[fr->callno],ies.encmethods); 07944 else 07945 iaxs[fr->callno]->encmethods = 0; 07946 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 07947 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 07948 if (!iaxs[fr->callno]) { 07949 ast_mutex_unlock(&iaxsl[fr->callno]); 07950 return 1; 07951 } 07952 break; 07953 case IAX_COMMAND_DPREQ: 07954 /* Request status in the dialplan */ 07955 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 07956 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 07957 if (iaxcompat) { 07958 /* Spawn a thread for the lookup */ 07959 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 07960 } else { 07961 /* Just look it up */ 07962 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 07963 } 07964 } 07965 break; 07966 case IAX_COMMAND_HANGUP: 07967 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07968 if (option_debug) 07969 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno); 07970 /* Set hangup cause according to remote */ 07971 if (ies.causecode && iaxs[fr->callno]->owner) 07972 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07973 /* Send ack immediately, before we destroy */ 07974 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07975 iax2_destroy(fr->callno); 07976 break; 07977 case IAX_COMMAND_REJECT: 07978 /* Set hangup cause according to remote */ 07979 if (ies.causecode && iaxs[fr->callno]->owner) 07980 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07981 07982 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07983 if (iaxs[fr->callno]->owner && authdebug) 07984 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 07985 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 07986 ies.cause ? ies.cause : "<Unknown>"); 07987 if (option_debug) 07988 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", 07989 fr->callno); 07990 } 07991 /* Send ack immediately, before we destroy */ 07992 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 07993 fr->ts, NULL, 0, fr->iseqno); 07994 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) 07995 iaxs[fr->callno]->error = EPERM; 07996 iax2_destroy(fr->callno); 07997 break; 07998 case IAX_COMMAND_TRANSFER: 07999 { 08000 struct ast_channel *bridged_chan; 08001 08002 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) { 08003 /* Set BLINDTRANSFER channel variables */ 08004 08005 ast_mutex_unlock(&iaxsl[fr->callno]); 08006 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name); 08007 ast_mutex_lock(&iaxsl[fr->callno]); 08008 if (!iaxs[fr->callno]) { 08009 ast_mutex_unlock(&iaxsl[fr->callno]); 08010 return 1; 08011 } 08012 08013 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name); 08014 if (!strcmp(ies.called_number, ast_parking_ext())) { 08015 struct ast_channel *saved_channel = iaxs[fr->callno]->owner; 08016 ast_mutex_unlock(&iaxsl[fr->callno]); 08017 if (iax_park(bridged_chan, saved_channel)) { 08018 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name); 08019 } else { 08020 ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name); 08021 } 08022 ast_mutex_lock(&iaxsl[fr->callno]); 08023 } else { 08024 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1)) 08025 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 08026 ies.called_number, iaxs[fr->callno]->context); 08027 else 08028 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 08029 ies.called_number, iaxs[fr->callno]->context); 08030 } 08031 } else 08032 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno); 08033 08034 break; 08035 } 08036 case IAX_COMMAND_ACCEPT: 08037 /* Ignore if call is already up or needs authentication or is a TBD */ 08038 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 08039 break; 08040 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 08041 /* Send ack immediately, before we destroy */ 08042 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08043 iax2_destroy(fr->callno); 08044 break; 08045 } 08046 if (ies.format) { 08047 iaxs[fr->callno]->peerformat = ies.format; 08048 } else { 08049 if (iaxs[fr->callno]->owner) 08050 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 08051 else 08052 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 08053 } 08054 if (option_verbose > 2) 08055 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)); 08056 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 08057 memset(&ied0, 0, sizeof(ied0)); 08058 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 08059 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 08060 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08061 if (!iaxs[fr->callno]) { 08062 ast_mutex_unlock(&iaxsl[fr->callno]); 08063 return 1; 08064 } 08065 if (authdebug) 08066 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); 08067 } else { 08068 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08069 if (iaxs[fr->callno]->owner) { 08070 /* Switch us to use a compatible format */ 08071 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 08072 if (option_verbose > 2) 08073 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 08074 retryowner2: 08075 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 08076 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 08077 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2; 08078 } 08079 08080 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 08081 /* Setup read/write formats properly. */ 08082 if (iaxs[fr->callno]->owner->writeformat) 08083 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 08084 if (iaxs[fr->callno]->owner->readformat) 08085 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 08086 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 08087 } 08088 } 08089 } 08090 if (iaxs[fr->callno]) { 08091 ast_mutex_lock(&dpcache_lock); 08092 dp = iaxs[fr->callno]->dpentries; 08093 while(dp) { 08094 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) { 08095 iax2_dprequest(dp, fr->callno); 08096 } 08097 dp = dp->peer; 08098 } 08099 ast_mutex_unlock(&dpcache_lock); 08100 } 08101 break; 08102 case IAX_COMMAND_POKE: 08103 /* Send back a pong packet with the original timestamp */ 08104 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 08105 if (!iaxs[fr->callno]) { 08106 ast_mutex_unlock(&iaxsl[fr->callno]); 08107 return 1; 08108 } 08109 break; 08110 case IAX_COMMAND_PING: 08111 { 08112 struct iax_ie_data pingied; 08113 construct_rr(iaxs[fr->callno], &pingied); 08114 /* Send back a pong packet with the original timestamp */ 08115 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 08116 } 08117 break; 08118 case IAX_COMMAND_PONG: 08119 /* Calculate ping time */ 08120 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 08121 /* save RR info */ 08122 save_rr(fr, &ies); 08123 08124 if (iaxs[fr->callno]->peerpoke) { 08125 peer = iaxs[fr->callno]->peerpoke; 08126 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 08127 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 08128 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 08129 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 08130 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 08131 } 08132 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 08133 if (iaxs[fr->callno]->pingtime > peer->maxms) { 08134 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 08135 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 08136 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 08137 } 08138 } 08139 peer->lastms = iaxs[fr->callno]->pingtime; 08140 if (peer->smoothing && (peer->lastms > -1)) 08141 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 08142 else if (peer->smoothing && peer->lastms < 0) 08143 peer->historicms = (0 + peer->historicms) / 2; 08144 else 08145 peer->historicms = iaxs[fr->callno]->pingtime; 08146 08147 /* Remove scheduled iax2_poke_noanswer */ 08148 if (peer->pokeexpire > -1) { 08149 if (!ast_sched_del(sched, peer->pokeexpire)) { 08150 peer_unref(peer); 08151 peer->pokeexpire = -1; 08152 } 08153 } 08154 /* Schedule the next cycle */ 08155 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 08156 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 08157 else 08158 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 08159 if (peer->pokeexpire == -1) 08160 peer_unref(peer); 08161 /* and finally send the ack */ 08162 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08163 /* And wrap up the qualify call */ 08164 iax2_destroy(fr->callno); 08165 peer->callno = 0; 08166 if (option_debug) 08167 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 08168 } 08169 break; 08170 case IAX_COMMAND_LAGRQ: 08171 case IAX_COMMAND_LAGRP: 08172 f.src = "LAGRQ"; 08173 f.mallocd = 0; 08174 f.offset = 0; 08175 f.samples = 0; 08176 iax_frame_wrap(fr, &f); 08177 if(f.subclass == IAX_COMMAND_LAGRQ) { 08178 /* Received a LAGRQ - echo back a LAGRP */ 08179 fr->af.subclass = IAX_COMMAND_LAGRP; 08180 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 08181 } else { 08182 /* Received LAGRP in response to our LAGRQ */ 08183 unsigned int ts; 08184 /* This is a reply we've been given, actually measure the difference */ 08185 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 08186 iaxs[fr->callno]->lag = ts - fr->ts; 08187 if (option_debug && iaxdebug) 08188 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", 08189 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 08190 } 08191 break; 08192 case IAX_COMMAND_AUTHREQ: 08193 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 08194 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>"); 08195 break; 08196 } 08197 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 08198 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 08199 .subclass = AST_CONTROL_HANGUP, 08200 }; 08201 ast_log(LOG_WARNING, 08202 "I don't know how to authenticate %s to %s\n", 08203 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 08204 iax2_queue_frame(fr->callno, &hangup_fr); 08205 } 08206 if (!iaxs[fr->callno]) { 08207 ast_mutex_unlock(&iaxsl[fr->callno]); 08208 return 1; 08209 } 08210 break; 08211 case IAX_COMMAND_AUTHREP: 08212 /* For security, always ack immediately */ 08213 if (delayreject) 08214 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08215 /* Ignore once we've started */ 08216 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 08217 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>"); 08218 break; 08219 } 08220 if (authenticate_verify(iaxs[fr->callno], &ies)) { 08221 if (authdebug) 08222 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); 08223 memset(&ied0, 0, sizeof(ied0)); 08224 auth_fail(fr->callno, IAX_COMMAND_REJECT); 08225 break; 08226 } 08227 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 08228 /* This might re-enter the IAX code and need the lock */ 08229 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 08230 } else 08231 exists = 0; 08232 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 08233 if (authdebug) 08234 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); 08235 memset(&ied0, 0, sizeof(ied0)); 08236 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 08237 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 08238 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08239 if (!iaxs[fr->callno]) { 08240 ast_mutex_unlock(&iaxsl[fr->callno]); 08241 return 1; 08242 } 08243 } else { 08244 /* Select an appropriate format */ 08245 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 08246 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08247 using_prefs = "reqonly"; 08248 } else { 08249 using_prefs = "disabled"; 08250 } 08251 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 08252 memset(&pref, 0, sizeof(pref)); 08253 strcpy(caller_pref_buf, "disabled"); 08254 strcpy(host_pref_buf, "disabled"); 08255 } else { 08256 using_prefs = "mine"; 08257 if (ies.codec_prefs) 08258 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 08259 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 08260 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 08261 pref = iaxs[fr->callno]->rprefs; 08262 using_prefs = "caller"; 08263 } else { 08264 pref = iaxs[fr->callno]->prefs; 08265 } 08266 } else /* if no codec_prefs IE do it the old way */ 08267 pref = iaxs[fr->callno]->prefs; 08268 08269 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 08270 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 08271 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 08272 } 08273 if (!format) { 08274 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08275 if (option_debug) 08276 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); 08277 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 08278 } 08279 if (!format) { 08280 if (authdebug) { 08281 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 08282 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); 08283 else 08284 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); 08285 } 08286 memset(&ied0, 0, sizeof(ied0)); 08287 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 08288 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 08289 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08290 if (!iaxs[fr->callno]) { 08291 ast_mutex_unlock(&iaxsl[fr->callno]); 08292 return 1; 08293 } 08294 } else { 08295 /* Pick one... */ 08296 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08297 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 08298 format = 0; 08299 } else { 08300 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 08301 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 08302 memset(&pref, 0, sizeof(pref)); 08303 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 08304 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08305 strcpy(caller_pref_buf,"disabled"); 08306 strcpy(host_pref_buf,"disabled"); 08307 } else { 08308 using_prefs = "mine"; 08309 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 08310 /* Do the opposite of what we tried above. */ 08311 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 08312 pref = iaxs[fr->callno]->prefs; 08313 } else { 08314 pref = iaxs[fr->callno]->rprefs; 08315 using_prefs = "caller"; 08316 } 08317 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 08318 } else /* if no codec_prefs IE do it the old way */ 08319 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08320 } 08321 } 08322 if (!format) { 08323 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08324 if (authdebug) { 08325 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 08326 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); 08327 else 08328 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); 08329 } 08330 memset(&ied0, 0, sizeof(ied0)); 08331 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 08332 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 08333 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08334 if (!iaxs[fr->callno]) { 08335 ast_mutex_unlock(&iaxsl[fr->callno]); 08336 return 1; 08337 } 08338 } 08339 } 08340 } 08341 if (format) { 08342 /* Authentication received */ 08343 memset(&ied1, 0, sizeof(ied1)); 08344 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 08345 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 08346 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 08347 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08348 if (option_verbose > 2) 08349 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" 08350 "%srequested format = %s,\n" 08351 "%srequested prefs = %s,\n" 08352 "%sactual format = %s,\n" 08353 "%shost prefs = %s,\n" 08354 "%spriority = %s\n", 08355 ast_inet_ntoa(sin.sin_addr), 08356 VERBOSE_PREFIX_4, 08357 ast_getformatname(iaxs[fr->callno]->peerformat), 08358 VERBOSE_PREFIX_4, 08359 caller_pref_buf, 08360 VERBOSE_PREFIX_4, 08361 ast_getformatname(format), 08362 VERBOSE_PREFIX_4, 08363 host_pref_buf, 08364 VERBOSE_PREFIX_4, 08365 using_prefs); 08366 08367 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08368 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 08369 iax2_destroy(fr->callno); 08370 } else { 08371 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 08372 /* If this is a TBD call, we're ready but now what... */ 08373 if (option_verbose > 2) 08374 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 08375 } 08376 } 08377 } 08378 break; 08379 case IAX_COMMAND_DIAL: 08380 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 08381 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 08382 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 08383 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 08384 if (authdebug) 08385 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); 08386 memset(&ied0, 0, sizeof(ied0)); 08387 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 08388 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 08389 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08390 if (!iaxs[fr->callno]) { 08391 ast_mutex_unlock(&iaxsl[fr->callno]); 08392 return 1; 08393 } 08394 } else { 08395 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08396 if (option_verbose > 2) 08397 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat); 08398 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08399 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 08400 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) 08401 iax2_destroy(fr->callno); 08402 } 08403 } 08404 break; 08405 case IAX_COMMAND_INVAL: 08406 iaxs[fr->callno]->error = ENOTCONN; 08407 if (option_debug) 08408 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno); 08409 iax2_destroy(fr->callno); 08410 if (option_debug) 08411 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno); 08412 break; 08413 case IAX_COMMAND_VNAK: 08414 if (option_debug) 08415 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); 08416 /* Force retransmission */ 08417 vnak_retransmit(fr->callno, fr->iseqno); 08418 break; 08419 case IAX_COMMAND_REGREQ: 08420 case IAX_COMMAND_REGREL: 08421 /* For security, always ack immediately */ 08422 if (delayreject) 08423 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08424 if (register_verify(fr->callno, &sin, &ies)) { 08425 if (!iaxs[fr->callno]) { 08426 ast_mutex_unlock(&iaxsl[fr->callno]); 08427 return 1; 08428 } 08429 /* Send delayed failure */ 08430 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 08431 break; 08432 } 08433 if (!iaxs[fr->callno]) { 08434 ast_mutex_unlock(&iaxsl[fr->callno]); 08435 return 1; 08436 } 08437 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 08438 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) { 08439 if (f.subclass == IAX_COMMAND_REGREL) 08440 memset(&sin, 0, sizeof(sin)); 08441 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) 08442 ast_log(LOG_WARNING, "Registry error\n"); 08443 if (!iaxs[fr->callno]) { 08444 ast_mutex_unlock(&iaxsl[fr->callno]); 08445 return 1; 08446 } 08447 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 08448 ast_mutex_unlock(&iaxsl[fr->callno]); 08449 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 08450 ast_mutex_lock(&iaxsl[fr->callno]); 08451 if (!iaxs[fr->callno]) { 08452 ast_mutex_unlock(&iaxsl[fr->callno]); 08453 return 1; 08454 } 08455 } 08456 break; 08457 } 08458 registry_authrequest(fr->callno); 08459 if (!iaxs[fr->callno]) { 08460 ast_mutex_unlock(&iaxsl[fr->callno]); 08461 return 1; 08462 } 08463 break; 08464 case IAX_COMMAND_REGACK: 08465 if (iax2_ack_registry(&ies, &sin, fr->callno)) 08466 ast_log(LOG_WARNING, "Registration failure\n"); 08467 /* Send ack immediately, before we destroy */ 08468 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08469 iax2_destroy(fr->callno); 08470 break; 08471 case IAX_COMMAND_REGREJ: 08472 if (iaxs[fr->callno]->reg) { 08473 if (authdebug) { 08474 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)); 08475 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>"); 08476 } 08477 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 08478 } 08479 /* Send ack immediately, before we destroy */ 08480 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08481 iax2_destroy(fr->callno); 08482 break; 08483 case IAX_COMMAND_REGAUTH: 08484 /* Authentication request */ 08485 if (registry_rerequest(&ies, fr->callno, &sin)) { 08486 memset(&ied0, 0, sizeof(ied0)); 08487 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 08488 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 08489 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08490 if (!iaxs[fr->callno]) { 08491 ast_mutex_unlock(&iaxsl[fr->callno]); 08492 return 1; 08493 } 08494 } 08495 break; 08496 case IAX_COMMAND_TXREJ: 08497 iaxs[fr->callno]->transferring = 0; 08498 if (option_verbose > 2) 08499 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 08500 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 08501 if (iaxs[fr->callno]->bridgecallno) { 08502 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 08503 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 08504 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 08505 } 08506 } 08507 break; 08508 case IAX_COMMAND_TXREADY: 08509 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 08510 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 08511 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 08512 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 08513 else 08514 iaxs[fr->callno]->transferring = TRANSFER_READY; 08515 if (option_verbose > 2) 08516 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 08517 if (iaxs[fr->callno]->bridgecallno) { 08518 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 08519 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 08520 /* They're both ready, now release them. */ 08521 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 08522 if (option_verbose > 2) 08523 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 08524 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 08525 08526 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 08527 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 08528 08529 memset(&ied0, 0, sizeof(ied0)); 08530 memset(&ied1, 0, sizeof(ied1)); 08531 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 08532 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 08533 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 08534 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 08535 } else { 08536 if (option_verbose > 2) 08537 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 08538 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 08539 08540 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 08541 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 08542 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 08543 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 08544 08545 /* Stop doing lag & ping requests */ 08546 stop_stuff(fr->callno); 08547 stop_stuff(iaxs[fr->callno]->bridgecallno); 08548 08549 memset(&ied0, 0, sizeof(ied0)); 08550 memset(&ied1, 0, sizeof(ied1)); 08551 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 08552 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 08553 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 08554 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 08555 } 08556 08557 } 08558 } 08559 } 08560 break; 08561 case IAX_COMMAND_TXREQ: 08562 try_transfer(iaxs[fr->callno], &ies); 08563 break; 08564 case IAX_COMMAND_TXCNT: 08565 if (iaxs[fr->callno]->transferring) 08566 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 08567 break; 08568 case IAX_COMMAND_TXREL: 08569 /* Send ack immediately, rather than waiting until we've changed addresses */ 08570 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08571 complete_transfer(fr->callno, &ies); 08572 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 08573 break; 08574 case IAX_COMMAND_TXMEDIA: 08575 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 08576 AST_LIST_LOCK(&iaxq.queue); 08577 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 08578 /* Cancel any outstanding frames and start anew */ 08579 if ((fr->callno == cur->callno) && (cur->transfer)) { 08580 cur->retries = -1; 08581 } 08582 } 08583 AST_LIST_UNLOCK(&iaxq.queue); 08584 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 08585 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 08586 } 08587 break; 08588 case IAX_COMMAND_DPREP: 08589 complete_dpreply(iaxs[fr->callno], &ies); 08590 break; 08591 case IAX_COMMAND_UNSUPPORT: 08592 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 08593 break; 08594 case IAX_COMMAND_FWDOWNL: 08595 /* Firmware download */ 08596 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 08597 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 08598 break; 08599 } 08600 memset(&ied0, 0, sizeof(ied0)); 08601 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 08602 if (res < 0) 08603 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08604 else if (res > 0) 08605 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08606 else 08607 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08608 if (!iaxs[fr->callno]) { 08609 ast_mutex_unlock(&iaxsl[fr->callno]); 08610 return 1; 08611 } 08612 break; 08613 default: 08614 if (option_debug) 08615 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); 08616 memset(&ied0, 0, sizeof(ied0)); 08617 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 08618 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 08619 } 08620 /* Don't actually pass these frames along */ 08621 if ((f.subclass != IAX_COMMAND_ACK) && 08622 (f.subclass != IAX_COMMAND_TXCNT) && 08623 (f.subclass != IAX_COMMAND_TXACC) && 08624 (f.subclass != IAX_COMMAND_INVAL) && 08625 (f.subclass != IAX_COMMAND_VNAK)) { 08626 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08627 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08628 } 08629 ast_mutex_unlock(&iaxsl[fr->callno]); 08630 return 1; 08631 } 08632 /* Unless this is an ACK or INVAL frame, ack it */ 08633 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08634 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08635 } else if (minivid) { 08636 f.frametype = AST_FRAME_VIDEO; 08637 if (iaxs[fr->callno]->videoformat > 0) 08638 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 08639 else { 08640 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n"); 08641 iax2_vnak(fr->callno); 08642 ast_mutex_unlock(&iaxsl[fr->callno]); 08643 return 1; 08644 } 08645 f.datalen = res - sizeof(*vh); 08646 if (f.datalen) 08647 f.data = thread->buf + sizeof(*vh); 08648 else 08649 f.data = NULL; 08650 #ifdef IAXTESTS 08651 if (test_resync) { 08652 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 08653 } else 08654 #endif /* IAXTESTS */ 08655 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 08656 } else { 08657 /* A mini frame */ 08658 f.frametype = AST_FRAME_VOICE; 08659 if (iaxs[fr->callno]->voiceformat > 0) 08660 f.subclass = iaxs[fr->callno]->voiceformat; 08661 else { 08662 if (option_debug) 08663 ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n"); 08664 iax2_vnak(fr->callno); 08665 ast_mutex_unlock(&iaxsl[fr->callno]); 08666 return 1; 08667 } 08668 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 08669 if (f.datalen < 0) { 08670 ast_log(LOG_WARNING, "Datalen < 0?\n"); 08671 ast_mutex_unlock(&iaxsl[fr->callno]); 08672 return 1; 08673 } 08674 if (f.datalen) 08675 f.data = thread->buf + sizeof(*mh); 08676 else 08677 f.data = NULL; 08678 #ifdef IAXTESTS 08679 if (test_resync) { 08680 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 08681 } else 08682 #endif /* IAXTESTS */ 08683 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 08684 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 08685 } 08686 /* Don't pass any packets until we're started */ 08687 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 08688 ast_mutex_unlock(&iaxsl[fr->callno]); 08689 return 1; 08690 } 08691 /* Common things */ 08692 f.src = "IAX2"; 08693 f.mallocd = 0; 08694 f.offset = 0; 08695 f.len = 0; 08696 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 08697 f.samples = ast_codec_get_samples(&f); 08698 /* We need to byteswap incoming slinear samples from network byte order */ 08699 if (f.subclass == AST_FORMAT_SLINEAR) 08700 ast_frame_byteswap_be(&f); 08701 } else 08702 f.samples = 0; 08703 iax_frame_wrap(fr, &f); 08704 08705 /* If this is our most recent packet, use it as our basis for timestamping */ 08706 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08707 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 08708 fr->outoforder = 0; 08709 } else { 08710 if (option_debug && iaxdebug && iaxs[fr->callno]) 08711 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); 08712 fr->outoforder = -1; 08713 } 08714 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 08715 duped_fr = iaxfrdup2(fr); 08716 if (duped_fr) { 08717 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 08718 } 08719 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08720 iaxs[fr->callno]->last = fr->ts; 08721 #if 1 08722 if (option_debug && iaxdebug) 08723 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 08724 #endif 08725 } 08726 08727 /* Always run again */ 08728 ast_mutex_unlock(&iaxsl[fr->callno]); 08729 return 1; 08730 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 7076 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().
07077 { 07078 struct iax2_thread *thread; 07079 socklen_t len; 07080 time_t t; 07081 static time_t last_errtime = 0; 07082 struct ast_iax2_full_hdr *fh; 07083 07084 if (!(thread = find_idle_thread())) { 07085 time(&t); 07086 if (t != last_errtime && option_debug) 07087 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n"); 07088 last_errtime = t; 07089 usleep(1); 07090 return 1; 07091 } 07092 07093 len = sizeof(thread->iosin); 07094 thread->iofd = fd; 07095 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 07096 thread->buf_size = sizeof(thread->readbuf); 07097 thread->buf = thread->readbuf; 07098 if (thread->buf_len < 0) { 07099 if (errno != ECONNREFUSED && errno != EAGAIN) 07100 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 07101 handle_error(); 07102 thread->iostate = IAX_IOSTATE_IDLE; 07103 signal_condition(&thread->lock, &thread->cond); 07104 return 1; 07105 } 07106 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 07107 thread->iostate = IAX_IOSTATE_IDLE; 07108 signal_condition(&thread->lock, &thread->cond); 07109 return 1; 07110 } 07111 07112 /* Determine if this frame is a full frame; if so, and any thread is currently 07113 processing a full frame for the same callno from this peer, then drop this 07114 frame (and the peer will retransmit it) */ 07115 fh = (struct ast_iax2_full_hdr *) thread->buf; 07116 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 07117 struct iax2_thread *cur = NULL; 07118 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 07119 07120 AST_LIST_LOCK(&active_list); 07121 AST_LIST_TRAVERSE(&active_list, cur, list) { 07122 if ((cur->ffinfo.callno == callno) && 07123 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 07124 break; 07125 } 07126 if (cur) { 07127 /* we found another thread processing a full frame for this call, 07128 so queue it up for processing later. */ 07129 defer_full_frame(thread, cur); 07130 AST_LIST_UNLOCK(&active_list); 07131 thread->iostate = IAX_IOSTATE_IDLE; 07132 signal_condition(&thread->lock, &thread->cond); 07133 return 1; 07134 } else { 07135 /* this thread is going to process this frame, so mark it */ 07136 thread->ffinfo.callno = callno; 07137 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 07138 thread->ffinfo.type = fh->type; 07139 thread->ffinfo.csub = fh->csub; 07140 } 07141 AST_LIST_UNLOCK(&active_list); 07142 } 07143 07144 /* Mark as ready and send on its way */ 07145 thread->iostate = IAX_IOSTATE_READY; 07146 #ifdef DEBUG_SCHED_MULTITHREAD 07147 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 07148 #endif 07149 signal_condition(&thread->lock, &thread->cond); 07150 07151 return 1; 07152 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 6863 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().
06864 { 06865 pthread_t newthread; 06866 struct dpreq_data *dpr; 06867 pthread_attr_t attr; 06868 06869 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 06870 return; 06871 06872 pthread_attr_init(&attr); 06873 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06874 06875 dpr->callno = callno; 06876 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 06877 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 06878 if (callerid) 06879 dpr->callerid = ast_strdup(callerid); 06880 if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) { 06881 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 06882 } 06883 06884 pthread_attr_destroy(&attr); 06885 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 9340 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().
09341 { 09342 pthread_attr_t attr; 09343 int threadcount = 0; 09344 int x; 09345 for (x = 0; x < iaxthreadcount; x++) { 09346 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread)); 09347 if (thread) { 09348 thread->type = IAX_TYPE_POOL; 09349 thread->threadnum = ++threadcount; 09350 ast_mutex_init(&thread->lock); 09351 ast_cond_init(&thread->cond, NULL); 09352 pthread_attr_init(&attr); 09353 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 09354 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 09355 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 09356 free(thread); 09357 thread = NULL; 09358 } 09359 AST_LIST_LOCK(&idle_list); 09360 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 09361 AST_LIST_UNLOCK(&idle_list); 09362 } 09363 } 09364 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL); 09365 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 09366 if (option_verbose > 1) 09367 ast_verbose(VERBOSE_PREFIX_2 "%d helper threads started\n", threadcount); 09368 return 0; 09369 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 6545 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
06546 { 06547 iax2_destroy_helper(iaxs[callno]); 06548 }
static void store_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1286 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().
01287 { 01288 if (!pvt->peercallno) { 01289 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01290 return; 01291 } 01292 01293 ao2_link(iax_peercallno_pvts, pvt); 01294 }
static void store_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1267 of file chan_iax2.c.
References ast_log(), iax_transfercallno_pvts, LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by try_transfer().
01268 { 01269 if (!pvt->transfercallno) { 01270 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 01271 return; 01272 } 01273 01274 ao2_link(iax_transfercallno_pvts, pvt); 01275 }
static int timing_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6732 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().
06733 { 06734 char buf[1024]; 06735 int res; 06736 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL; 06737 int processed = 0; 06738 int totalcalls = 0; 06739 #ifdef DAHDI_TIMERACK 06740 int x = 1; 06741 #endif 06742 struct timeval now; 06743 if (iaxtrunkdebug) 06744 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA); 06745 gettimeofday(&now, NULL); 06746 if (events & AST_IO_PRI) { 06747 #ifdef DAHDI_TIMERACK 06748 /* Great, this is a timing interface, just call the ioctl */ 06749 if (ioctl(fd, DAHDI_TIMERACK, &x)) { 06750 ast_log(LOG_WARNING, "Unable to acknowledge timer. IAX trunking will fail!\n"); 06751 usleep(1); 06752 return -1; 06753 } 06754 #endif 06755 } else { 06756 /* Read and ignore from the pseudo channel for timing */ 06757 res = read(fd, buf, sizeof(buf)); 06758 if (res < 1) { 06759 ast_log(LOG_WARNING, "Unable to read from timing fd\n"); 06760 return 1; 06761 } 06762 } 06763 /* For each peer that supports trunking... */ 06764 ast_mutex_lock(&tpeerlock); 06765 tpeer = tpeers; 06766 while(tpeer) { 06767 processed++; 06768 res = 0; 06769 ast_mutex_lock(&tpeer->lock); 06770 /* We can drop a single tpeer per pass. That makes all this logic 06771 substantially easier */ 06772 if (!drop && iax2_trunk_expired(tpeer, &now)) { 06773 /* Take it out of the list, but don't free it yet, because it 06774 could be in use */ 06775 if (prev) 06776 prev->next = tpeer->next; 06777 else 06778 tpeers = tpeer->next; 06779 drop = tpeer; 06780 } else { 06781 res = send_trunk(tpeer, &now); 06782 if (iaxtrunkdebug) 06783 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); 06784 } 06785 totalcalls += res; 06786 res = 0; 06787 ast_mutex_unlock(&tpeer->lock); 06788 prev = tpeer; 06789 tpeer = tpeer->next; 06790 } 06791 ast_mutex_unlock(&tpeerlock); 06792 if (drop) { 06793 ast_mutex_lock(&drop->lock); 06794 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 06795 because by the time they could get tpeerlock, we've already grabbed it */ 06796 if (option_debug) 06797 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 06798 if (drop->trunkdata) { 06799 free(drop->trunkdata); 06800 drop->trunkdata = NULL; 06801 } 06802 ast_mutex_unlock(&drop->lock); 06803 ast_mutex_destroy(&drop->lock); 06804 free(drop); 06805 06806 } 06807 if (iaxtrunkdebug) 06808 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 06809 iaxtrunkdebug =0; 06810 return 1; 06811 }
static int transfercallno_pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11310 of file chan_iax2.c.
References chan_iax2_pvt::frames_received, and match().
Referenced by load_module().
11311 { 11312 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 11313 11314 /* The frames_received field is used to hold whether we're matching 11315 * against a full frame or not ... */ 11316 11317 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt, 11318 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 11319 }
static int transfercallno_pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 11303 of file chan_iax2.c.
References chan_iax2_pvt::transfercallno.
Referenced by load_module().
11304 { 11305 const struct chan_iax2_pvt *pvt = obj; 11306 11307 return pvt->transfercallno; 11308 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 2182 of file chan_iax2.c.
References ast_log(), errno, f, handle_error(), LOG_DEBUG, and option_debug.
Referenced by send_trunk().
02183 { 02184 int res; 02185 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 02186 sizeof(*sin)); 02187 if (res < 0) { 02188 if (option_debug) 02189 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 02190 handle_error(); 02191 } else 02192 res = 0; 02193 return res; 02194 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 1870 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().
01871 { 01872 struct stat stbuf; 01873 struct iax_firmware *cur; 01874 int ifd; 01875 int fd; 01876 int res; 01877 01878 struct ast_iax2_firmware_header *fwh, fwh2; 01879 struct MD5Context md5; 01880 unsigned char sum[16]; 01881 unsigned char buf[1024]; 01882 int len, chunk; 01883 char *s2; 01884 char *last; 01885 s2 = alloca(strlen(s) + 100); 01886 if (!s2) { 01887 ast_log(LOG_WARNING, "Alloca failed!\n"); 01888 return -1; 01889 } 01890 last = strrchr(s, '/'); 01891 if (last) 01892 last++; 01893 else 01894 last = s; 01895 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 01896 res = stat(s, &stbuf); 01897 if (res < 0) { 01898 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 01899 return -1; 01900 } 01901 /* Make sure it's not a directory */ 01902 if (S_ISDIR(stbuf.st_mode)) 01903 return -1; 01904 ifd = open(s, O_RDONLY); 01905 if (ifd < 0) { 01906 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 01907 return -1; 01908 } 01909 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600); 01910 if (fd < 0) { 01911 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 01912 close(ifd); 01913 return -1; 01914 } 01915 /* Unlink our newly created file */ 01916 unlink(s2); 01917 01918 /* Now copy the firmware into it */ 01919 len = stbuf.st_size; 01920 while(len) { 01921 chunk = len; 01922 if (chunk > sizeof(buf)) 01923 chunk = sizeof(buf); 01924 res = read(ifd, buf, chunk); 01925 if (res != chunk) { 01926 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01927 close(ifd); 01928 close(fd); 01929 return -1; 01930 } 01931 res = write(fd, buf, chunk); 01932 if (res != chunk) { 01933 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01934 close(ifd); 01935 close(fd); 01936 return -1; 01937 } 01938 len -= chunk; 01939 } 01940 close(ifd); 01941 /* Return to the beginning */ 01942 lseek(fd, 0, SEEK_SET); 01943 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 01944 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 01945 close(fd); 01946 return -1; 01947 } 01948 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 01949 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 01950 close(fd); 01951 return -1; 01952 } 01953 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 01954 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 01955 close(fd); 01956 return -1; 01957 } 01958 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 01959 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 01960 close(fd); 01961 return -1; 01962 } 01963 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 01964 if (fwh == (void *) -1) { 01965 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 01966 close(fd); 01967 return -1; 01968 } 01969 MD5Init(&md5); 01970 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 01971 MD5Final(sum, &md5); 01972 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 01973 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 01974 munmap((void*)fwh, stbuf.st_size); 01975 close(fd); 01976 return -1; 01977 } 01978 cur = waresl.wares; 01979 while(cur) { 01980 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 01981 /* Found a candidate */ 01982 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 01983 /* The version we have on loaded is older, load this one instead */ 01984 break; 01985 /* This version is no newer than what we have. Don't worry about it. 01986 We'll consider it a proper load anyhow though */ 01987 munmap((void*)fwh, stbuf.st_size); 01988 close(fd); 01989 return 0; 01990 } 01991 cur = cur->next; 01992 } 01993 if (!cur) { 01994 /* Allocate a new one and link it */ 01995 if ((cur = ast_calloc(1, sizeof(*cur)))) { 01996 cur->fd = -1; 01997 cur->next = waresl.wares; 01998 waresl.wares = cur; 01999 } 02000 } 02001 if (cur) { 02002 if (cur->fwh) { 02003 munmap((void*)cur->fwh, cur->mmaplen); 02004 } 02005 if (cur->fd > -1) 02006 close(cur->fd); 02007 cur->fwh = fwh; 02008 cur->fd = fd; 02009 cur->mmaplen = stbuf.st_size; 02010 cur->dead = 0; 02011 } 02012 return 0; 02013 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5935 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(), store_by_transfercallno(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.
Referenced by socket_process().
05936 { 05937 int newcall = 0; 05938 char newip[256]; 05939 struct iax_ie_data ied; 05940 struct sockaddr_in new; 05941 05942 05943 memset(&ied, 0, sizeof(ied)); 05944 if (ies->apparent_addr) 05945 bcopy(ies->apparent_addr, &new, sizeof(new)); 05946 if (ies->callno) 05947 newcall = ies->callno; 05948 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 05949 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05950 return -1; 05951 } 05952 pvt->transfercallno = newcall; 05953 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 05954 inet_aton(newip, &pvt->transfer.sin_addr); 05955 pvt->transfer.sin_family = AF_INET; 05956 pvt->transferring = TRANSFER_BEGIN; 05957 pvt->transferid = ies->transferid; 05958 store_by_transfercallno(pvt); 05959 if (ies->transferid) 05960 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 05961 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 05962 return 0; 05963 }
static int uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1103 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), and socket_process().
01104 { 01105 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01106 if (csub & IAX_FLAG_SC_LOG) { 01107 /* special case for 'compressed' -1 */ 01108 if (csub == 0xff) 01109 return -1; 01110 else 01111 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01112 } 01113 else 01114 return csub; 01115 }
static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 6213 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().
06214 { 06215 if (peer->expire > -1) { 06216 if (!ast_sched_del(sched, peer->expire)) { 06217 peer->expire = -1; 06218 peer_unref(peer); 06219 } 06220 } 06221 06222 if (peer->pokeexpire > -1) { 06223 if (!ast_sched_del(sched, peer->pokeexpire)) { 06224 peer->pokeexpire = -1; 06225 peer_unref(peer); 06226 } 06227 } 06228 06229 ao2_unlink(peers, peer); 06230 }
static int unload_module | ( | void | ) | [static] |
Definition at line 11269 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), and iaxpeer_function.
11270 { 11271 ast_custom_function_unregister(&iaxpeer_function); 11272 return __unload_module(); 11273 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3661 of file chan_iax2.c.
References ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
03662 { 03663 ast_mutex_unlock(&iaxsl[callno1]); 03664 ast_mutex_unlock(&iaxsl[callno0]); 03665 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2634 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().
02635 { 02636 /* Video mini frames only encode the lower 15 bits of the session 02637 * timestamp, but other frame types (e.g. audio) encode 16 bits. */ 02638 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16; 02639 const int lower_mask = (1 << ts_shift) - 1; 02640 const int upper_mask = ~lower_mask; 02641 const int last_upper = iaxs[fr->callno]->last & upper_mask; 02642 02643 if ( (fr->ts & upper_mask) == last_upper ) { 02644 const int x = fr->ts - iaxs[fr->callno]->last; 02645 const int threshold = (ts_shift == 15) ? 25000 : 50000; 02646 02647 if (x < -threshold) { 02648 /* Sudden big jump backwards in timestamp: 02649 What likely happened here is that miniframe timestamp has circled but we haven't 02650 gotten the update from the main packet. We'll just pretend that we did, and 02651 update the timestamp appropriately. */ 02652 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask); 02653 if (option_debug && iaxdebug) 02654 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n"); 02655 } else if (x > threshold) { 02656 /* Sudden apparent big jump forwards in timestamp: 02657 What's likely happened is this is an old miniframe belonging to the previous 02658 top 15 or 16-bit timestamp that has turned up out of order. 02659 Adjust the timestamp appropriately. */ 02660 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask); 02661 if (option_debug && iaxdebug) 02662 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n"); 02663 } 02664 } 02665 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2669 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().
02670 { 02671 int when; 02672 02673 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 02674 02675 when = jb_next(pvt->jb) - when; 02676 02677 AST_SCHED_DEL(sched, pvt->jbid); 02678 02679 if(when <= 0) { 02680 /* XXX should really just empty until when > 0.. */ 02681 when = 1; 02682 } 02683 02684 pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno)); 02685 }
static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 1519 of file chan_iax2.c.
References ast_log(), LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by __find_callno(), and make_trunk().
01520 { 01521 int max = 1; 01522 int x; 01523 /* XXX Prolly don't need locks here XXX */ 01524 for (x=1;x<TRUNK_CALL_START - 1; x++) { 01525 if (iaxs[x]) 01526 max = x + 1; 01527 } 01528 maxnontrunkcall = max; 01529 if (option_debug && iaxdebug) 01530 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max); 01531 }
static void update_max_trunk | ( | void | ) | [static] |
Definition at line 1306 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().
01307 { 01308 int max = TRUNK_CALL_START; 01309 int x; 01310 01311 /* XXX Prolly don't need locks here XXX */ 01312 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 01313 if (iaxs[x]) { 01314 max = x + 1; 01315 } 01316 } 01317 01318 maxtrunkcall = max; 01319 if (option_debug && iaxdebug) 01320 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max); 01321 }
static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2253 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().
02254 { 02255 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 02256 struct ast_iax2_full_hdr *fh = f->data; 02257 /* Mark this as a retransmission */ 02258 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 02259 /* Update iseqno */ 02260 f->iseqno = iaxs[f->callno]->iseqno; 02261 fh->iseqno = f->iseqno; 02262 return 0; 02263 }
static int update_registry | ( | struct sockaddr_in * | sin, | |
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 6324 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().
06325 { 06326 /* Called from IAX thread only, with proper iaxsl lock */ 06327 struct iax_ie_data ied; 06328 struct iax2_peer *p; 06329 int msgcount; 06330 char data[80]; 06331 int version; 06332 const char *peer_name; 06333 int res = -1; 06334 06335 memset(&ied, 0, sizeof(ied)); 06336 06337 peer_name = ast_strdupa(iaxs[callno]->peer); 06338 06339 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 06340 ast_mutex_unlock(&iaxsl[callno]); 06341 if (!(p = find_peer(peer_name, 1))) { 06342 ast_mutex_lock(&iaxsl[callno]); 06343 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 06344 return -1; 06345 } 06346 ast_mutex_lock(&iaxsl[callno]); 06347 if (!iaxs[callno]) 06348 goto return_unref; 06349 06350 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 06351 if (sin->sin_addr.s_addr) { 06352 time_t nowtime; 06353 time(&nowtime); 06354 realtime_update_peer(peer_name, sin, nowtime); 06355 } else { 06356 realtime_update_peer(peer_name, sin, 0); 06357 } 06358 } 06359 if (inaddrcmp(&p->addr, sin)) { 06360 if (iax2_regfunk) 06361 iax2_regfunk(p->name, 1); 06362 /* Stash the IP address from which they registered */ 06363 memcpy(&p->addr, sin, sizeof(p->addr)); 06364 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 06365 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 06366 ast_db_put("IAX/Registry", p->name, data); 06367 if (option_verbose > 2) 06368 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 06369 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 06370 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 06371 register_peer_exten(p, 1); 06372 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06373 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 06374 if (option_verbose > 2) 06375 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 06376 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 06377 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 06378 register_peer_exten(p, 0); 06379 ast_db_del("IAX/Registry", p->name); 06380 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06381 } 06382 /* Update the host */ 06383 /* Verify that the host is really there */ 06384 iax2_poke_peer(p, callno); 06385 } 06386 06387 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 06388 if (!iaxs[callno]) { 06389 res = -1; 06390 goto return_unref; 06391 } 06392 06393 /* Store socket fd */ 06394 p->sockfd = fd; 06395 /* Setup the expiry */ 06396 if (p->expire > -1) { 06397 if (!ast_sched_del(sched, p->expire)) { 06398 p->expire = -1; 06399 peer_unref(p); 06400 } 06401 } 06402 /* treat an unspecified refresh interval as the minimum */ 06403 if (!refresh) 06404 refresh = min_reg_expire; 06405 if (refresh > max_reg_expire) { 06406 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 06407 p->name, max_reg_expire, refresh); 06408 p->expiry = max_reg_expire; 06409 } else if (refresh < min_reg_expire) { 06410 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 06411 p->name, min_reg_expire, refresh); 06412 p->expiry = min_reg_expire; 06413 } else { 06414 p->expiry = refresh; 06415 } 06416 if (p->expiry && sin->sin_addr.s_addr) { 06417 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 06418 if (p->expire == -1) 06419 peer_unref(p); 06420 } 06421 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 06422 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 06423 if (sin->sin_addr.s_addr) { 06424 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 06425 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 06426 if (!ast_strlen_zero(p->mailbox)) { 06427 int new, old; 06428 ast_app_inboxcount(p->mailbox, &new, &old); 06429 if (new > 255) 06430 new = 255; 06431 if (old > 255) 06432 old = 255; 06433 msgcount = (old << 8) | new; 06434 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 06435 } 06436 if (ast_test_flag(p, IAX_HASCALLERID)) { 06437 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 06438 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 06439 } 06440 } 06441 version = iax_check_version(devtype); 06442 if (version) 06443 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 06444 06445 res = 0; 06446 06447 return_unref: 06448 peer_unref(p); 06449 06450 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 06451 }
static int user_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1150 of file chan_iax2.c.
References iax2_user::name.
Referenced by load_module().
01151 { 01152 struct iax2_user *user = obj, *user2 = arg; 01153 01154 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0; 01155 }
static int user_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9972 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
09973 { 09974 struct iax2_user *user = obj; 09975 09976 ast_set_flag(user, IAX_DELME); 09977 09978 return 0; 09979 }
static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 9736 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().
09737 { 09738 struct iax2_user *user = obj; 09739 09740 ast_free_ha(user->ha); 09741 free_context(user->contexts); 09742 if(user->vars) { 09743 ast_variables_destroy(user->vars); 09744 user->vars = NULL; 09745 } 09746 ast_string_field_free_memory(user); 09747 }
static int user_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1140 of file chan_iax2.c.
References ast_str_hash(), and iax2_user::name.
Referenced by load_module().
01141 { 01142 const struct iax2_user *user = obj; 01143 01144 return ast_str_hash(user->name); 01145 }
Definition at line 1198 of file chan_iax2.c.
References ao2_ref().
01199 { 01200 ao2_ref(user, +1); 01201 return user; 01202 }
Definition at line 1204 of file chan_iax2.c.
References ao2_ref().
Referenced by authenticate_request(), authenticate_verify(), build_user(), check_access(), iax2_destroy_helper(), iax2_prune_realtime(), iax2_show_users(), prune_users(), and set_config().
01205 { 01206 ao2_ref(user, -1); 01207 return NULL; 01208 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 6646 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().
06647 { 06648 struct iax_frame *f; 06649 06650 AST_LIST_LOCK(&iaxq.queue); 06651 AST_LIST_TRAVERSE(&iaxq.queue, f, list) { 06652 /* Send a copy immediately */ 06653 if ((f->callno == callno) && iaxs[f->callno] && 06654 ((unsigned char ) (f->oseqno - last) < 128) && 06655 (f->retries >= 0)) { 06656 send_packet(f); 06657 } 06658 } 06659 AST_LIST_UNLOCK(&iaxq.queue); 06660 }
static int wait_for_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 3559 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().
03560 { 03561 unsigned short callno = pvt->callno; 03562 03563 if (!pvt->peercallno) { 03564 /* We don't know the remote side's call number, yet. :( */ 03565 int count = 10; 03566 while (count-- && pvt && !pvt->peercallno) { 03567 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 03568 pvt = iaxs[callno]; 03569 } 03570 if (!pvt->peercallno) { 03571 return -1; 03572 } 03573 } 03574 03575 return 0; 03576 }
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 11445 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 11445 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 11064 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 11069 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 11079 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 11074 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 11059 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 11033 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 11025 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 11017 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 10975 of file chan_iax2.c.
enum { ... } iax2_state |
struct ast_switch iax2_switch [static] |
struct ast_channel_tech iax2_tech [static] |
Definition at line 873 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 11041 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().
struct ao2_container* iax_transfercallno_pvts [static] |
Another container of iax2_pvt structures.
*
Active IAX2 pvt stucts used during transfering a call are stored here.
Definition at line 831 of file chan_iax2.c.
Referenced by __find_callno(), __unload_module(), load_module(), remove_by_transfercallno(), and store_by_transfercallno().
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 838 of file chan_iax2.c.
int maxtrunkcall = TRUNK_CALL_START [static] |
Definition at line 837 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 11037 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 11029 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 11021 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 8980 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 8982 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 10971 of file chan_iax2.c.
char* psyn = "Provision a calling IAXy with a given template" [static] |
Definition at line 8981 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 10963 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 10991 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 11009 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 10995 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 10967 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 11003 of file chan_iax2.c.
char show_prov_usage[] [static] |
Definition at line 10979 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 11013 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 10959 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 10999 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 10986 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().