#include "asterisk.h"
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <dirent.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <signal.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <regex.h>
#include "asterisk/lock.h"
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/config.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/translate.h"
#include "asterisk/md5.h"
#include "asterisk/cdr.h"
#include "asterisk/crypto.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/app.h"
#include "asterisk/astdb.h"
#include "asterisk/musiconhold.h"
#include "asterisk/features.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/localtime.h"
#include "asterisk/aes.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/netsock.h"
#include "asterisk/stringfields.h"
#include "asterisk/linkedlists.h"
#include "asterisk/astobj2.h"
#include "iax2.h"
#include "iax2-parser.h"
#include "iax2-provision.h"
#include "jitterbuf.h"
Go to the source code of this file.
Data Structures | |
struct | ast_firmware_list |
struct | ast_iax2_queue |
struct | chan_iax2_pvt |
struct | create_addr_info |
struct | dpreq_data |
struct | iax2_context |
struct | iax2_dpcache |
struct | iax2_peer |
struct | iax2_pkt_buf |
struct | iax2_registry |
struct | iax2_thread |
struct | iax2_trunk_peer |
struct | iax2_user |
struct | iax_dual |
struct | iax_firmware |
struct | iax_rr |
struct | parsed_dial_string |
Defines | |
#define | CACHE_FLAG_CANEXIST (1 << 2) |
#define | CACHE_FLAG_EXISTS (1 << 0) |
#define | CACHE_FLAG_MATCHMORE (1 << 7) |
#define | CACHE_FLAG_NONEXISTENT (1 << 1) |
#define | CACHE_FLAG_PENDING (1 << 3) |
#define | CACHE_FLAG_TIMEOUT (1 << 4) |
#define | CACHE_FLAG_TRANSMITTED (1 << 5) |
#define | CACHE_FLAG_UNKNOWN (1 << 6) |
#define | CALLNO_TO_PTR(a) ((void *)(unsigned long)(a)) |
#define | DEBUG_SCHED_MULTITHREAD |
#define | DEBUG_SUPPORT |
#define | DEFAULT_DROP 3 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_THREAD_COUNT 100 |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_RETRY_TIME 1000 |
#define | DEFAULT_THREAD_COUNT 10 |
#define | DEFAULT_TRUNKDATA 640 * 10 |
#define | FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s\n" |
#define | FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
#define | FORMAT "%-15.15s %-15d %-15d\n" |
#define | FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" |
#define | FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
#define | FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" |
#define | FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
#define | FORMAT2 "%-15.15s %-15.15s %-15.15s\n" |
#define | FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" |
#define | FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
#define | FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
#define | GAMMA (0.01) |
#define | IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
#define | IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
#define | IAX_CAPABILITY_LOWBANDWIDTH |
#define | IAX_CAPABILITY_LOWFREE |
#define | IAX_CAPABILITY_MEDBANDWIDTH |
#define | IAX_IOSTATE_IDLE 0 |
#define | IAX_IOSTATE_PROCESSING 2 |
#define | IAX_IOSTATE_READY 1 |
#define | IAX_IOSTATE_SCHEDREADY 3 |
#define | IAX_TYPE_DYNAMIC 2 |
#define | IAX_TYPE_POOL 1 |
#define | IPTOS_MINCOST 0x02 |
#define | MAX_JITTER_BUFFER 50 |
#define | MAX_PEER_BUCKETS 1 |
#define | MAX_RETRY_TIME 10000 |
#define | MAX_TIMESTAMP_SKEW 160 |
#define | MAX_TRUNKDATA 640 * 200 |
#define | MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define | MEMORY_SIZE 100 |
#define | MIN_JITTER_BUFFER 10 |
#define | MIN_RETRY_TIME 100 |
#define | MIN_REUSE_TIME 60 |
#define | NEW_ALLOW 1 |
#define | NEW_FORCE 2 |
#define | NEW_PREVENT 0 |
#define | PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a)) |
#define | SCHED_MULTITHREADED |
#define | schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__) |
#define | TRUNK_CALL_START 0x4000 |
#define | TS_GAP_FOR_JB_RESYNC 5000 |
Enumerations | |
enum | { IAX_STATE_STARTED = (1 << 0), IAX_STATE_AUTHENTICATED = (1 << 1), IAX_STATE_TBD = (1 << 2), IAX_STATE_UNCHANGED = (1 << 3) } |
enum | { IAX_HASCALLERID = (1 << 0), IAX_DELME = (1 << 1), IAX_TEMPONLY = (1 << 2), IAX_TRUNK = (1 << 3), IAX_NOTRANSFER = (1 << 4), IAX_USEJITTERBUF = (1 << 5), IAX_DYNAMIC = (1 << 6), IAX_SENDANI = (1 << 7), IAX_ALREADYGONE = (1 << 9), IAX_PROVISION = (1 << 10), IAX_QUELCH = (1 << 11), IAX_ENCRYPTED = (1 << 12), IAX_KEYPOPULATED = (1 << 13), IAX_CODEC_USER_FIRST = (1 << 14), IAX_CODEC_NOPREFS = (1 << 15), IAX_CODEC_NOCAP = (1 << 16), IAX_RTCACHEFRIENDS = (1 << 17), IAX_RTUPDATE = (1 << 18), IAX_RTAUTOCLEAR = (1 << 19), IAX_FORCEJITTERBUF = (1 << 20), IAX_RTIGNOREREGEXPIRE = (1 << 21), IAX_TRUNKTIMESTAMPS = (1 << 22), IAX_TRANSFERMEDIA = (1 << 23), IAX_MAXAUTHREQ = (1 << 24), IAX_DELAYPBXSTART = (1 << 25), 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 void | __get_from_jb (const void *p) |
static void | __iax2_do_register_s (const void *data) |
static void | __iax2_poke_noanswer (const void *data) |
static void | __iax2_poke_peer_s (const void *data) |
static int | __iax2_show_peers (int manager, int fd, struct mansession *s, int argc, char *argv[]) |
static int | __schedule_action (void(*func)(const void *data), const void *data, const char *funcname) |
static int | __send_command (struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, int now, int transfer, int final) |
static void | __send_lagrq (const void *data) |
static void | __send_ping (const void *data) |
static int | __unload_module (void) |
static int | apply_context (struct iax2_context *con, const char *context) |
static int | ast_cli_netstats (struct mansession *s, int fd, int limit_fmt) |
static struct ast_channel * | ast_iax2_new (int callno, int state, int capability) |
Create new call, interface with the PBX core. | |
static | AST_LIST_HEAD_STATIC (dynamic_list, iax2_thread) |
static | AST_LIST_HEAD_STATIC (active_list, iax2_thread) |
static | AST_LIST_HEAD_STATIC (idle_list, iax2_thread) |
static | AST_LIST_HEAD_STATIC (registrations, iax2_registry) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Inter Asterisk eXchange (Ver 2)",.load=load_module,.unload=unload_module,.reload=reload,) | |
AST_MUTEX_DEFINE_STATIC (dpcache_lock) | |
AST_MUTEX_DEFINE_STATIC (tpeerlock) | |
AST_MUTEX_DEFINE_STATIC (sched_lock) | |
static int | attempt_transmit (const void *data) |
static int | auth_fail (int callno, int failcode) |
static int | auth_reject (const void *data) |
static int | authenticate (const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx) |
static int | authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey) |
static int | authenticate_request (int call_num) |
static int | authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies) |
static int | auto_congest (const void *data) |
static int | auto_hangup (const void *data) |
static struct iax2_context * | build_context (char *context) |
static void | build_enc_keys (const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx) |
static struct iax2_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
Create peer structure based on configuration. | |
static struct iax2_user * | build_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
Create in-memory user structure from configuration. | |
static int | cache_get_callno_locked (const char *data) |
static unsigned int | calc_rxstamp (struct chan_iax2_pvt *p, unsigned int offset) |
static unsigned int | calc_timestamp (struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f) |
static unsigned int | calc_txpeerstamp (struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv) |
static int | check_access (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
static int | check_provisioning (struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver) |
static int | check_srcaddr (struct sockaddr *sa, socklen_t salen) |
Check if address can be used as packet source. | |
static int | complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
static char * | complete_iax2_show_peer (const char *line, const char *word, int pos, int state) |
static int | complete_transfer (int callno, struct iax_ies *ies) |
static unsigned char | compress_subclass (int subclass) |
static void | construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) |
static int | create_addr (const char *peername, struct sockaddr_in *sin, struct create_addr_info *cai) |
static int | decode_frame (aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
static int | decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
static void | defer_full_frame (struct iax2_thread *from_here, struct iax2_thread *to_here) |
Queue the last read full frame for processing by a certain thread. | |
static void | delete_users (void) |
static void | destroy_firmware (struct iax_firmware *cur) |
static void | dp_lookup (int callno, const char *context, const char *callednum, const char *callerid, int skiplock) |
static void * | dp_lookup_thread (void *data) |
static int | encrypt_frame (aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen) |
static int | expire_registry (const void *data) |
static struct iax2_dpcache * | find_cache (struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority) |
static int | find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) |
static struct iax2_thread * | find_idle_thread (void) |
static struct iax2_peer * | find_peer (const char *name, int realtime) |
static struct iax2_trunk_peer * | find_tpeer (struct sockaddr_in *sin, int fd) |
static unsigned int | fix_peerts (struct timeval *tv, int callno, unsigned int ts) |
static void | free_context (struct iax2_context *con) |
static int | function_iaxpeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
static int | get_auth_methods (char *value) |
static int | get_encrypt_methods (const char *s) |
static int | get_from_jb (const void *p) |
static void | handle_deferred_full_frames (struct iax2_thread *thread) |
Handle any deferred full frames for this thread. | |
static int | handle_error (void) |
static int | iax2_ack_registry (struct iax_ies *ies, struct sockaddr_in *sin, int callno) |
Acknowledgment received for OUR registration. | |
static int | iax2_answer (struct ast_channel *c) |
static enum ast_bridge_result | iax2_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
static int | iax2_call (struct ast_channel *c, char *dest, int timeout) |
static int | iax2_canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
part of the IAX2 dial plan switch interface | |
static unsigned int | iax2_datetime (const char *tz) |
static void | iax2_destroy (int callno) |
static void | iax2_destroy_helper (struct chan_iax2_pvt *pvt) |
static int | iax2_devicestate (void *data) |
Part of the device state notification system ---. | |
static int | iax2_digit_begin (struct ast_channel *c, char digit) |
static int | iax2_digit_end (struct ast_channel *c, char digit, unsigned int duration) |
static int | iax2_do_debug (int fd, int argc, char *argv[]) |
static int | iax2_do_jb_debug (int fd, int argc, char *argv[]) |
static int | iax2_do_register (struct iax2_registry *reg) |
static int | iax2_do_register_s (const void *data) |
static int | iax2_do_trunk_debug (int fd, int argc, char *argv[]) |
static void | iax2_dprequest (struct iax2_dpcache *dp, int callno) |
static int | iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Execute IAX2 dialplan switch. | |
static int | iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Part of the IAX2 switch interface. | |
static int | iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan) |
static void | iax2_frame_free (struct iax_frame *fr) |
static int | iax2_getpeername (struct sockaddr_in sin, char *host, int len) |
static int | iax2_getpeertrunk (struct sockaddr_in sin) |
static int | iax2_hangup (struct ast_channel *c) |
static int | iax2_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen) |
static int | iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Part of the IAX2 Switch interface. | |
static int | iax2_no_debug (int fd, int argc, char *argv[]) |
static int | iax2_no_jb_debug (int fd, int argc, char *argv[]) |
static int | iax2_no_trunk_debug (int fd, int argc, char *argv[]) |
static int | iax2_poke_noanswer (const void *data) |
static int | iax2_poke_peer (struct iax2_peer *peer, int heldcall) |
static int | iax2_poke_peer_cb (void *obj, void *arg, int flags) |
static int | iax2_poke_peer_s (const void *data) |
static int | iax2_predestroy (int callno) |
static void * | iax2_process_thread (void *data) |
static void | iax2_process_thread_cleanup (void *data) |
static int | iax2_prov_app (struct ast_channel *chan, void *data) |
static int | iax2_prov_cmd (int fd, int argc, char *argv[]) |
static char * | iax2_prov_complete_template_3rd (const char *line, const char *word, int pos, int state) |
static int | iax2_provision (struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force) |
static int | iax2_prune_realtime (int fd, int argc, char *argv[]) |
static int | iax2_queue_control_data (int callno, enum ast_control_frame_type control, const void *data, size_t datalen) |
Queue a control frame on the ast_channel owner. | |
static int | iax2_queue_frame (int callno, struct ast_frame *f) |
Queue a frame to a call's owning asterisk channel. | |
static int | iax2_queue_hangup (int callno) |
Queue a hangup frame on the ast_channel owner. | |
static struct ast_frame * | iax2_read (struct ast_channel *c) |
static int | iax2_register (char *value, int lineno) |
static int | iax2_reload (int fd, int argc, char *argv[]) |
static struct ast_channel * | iax2_request (const char *type, int format, void *data, int *cause) |
static int | iax2_sched_add (struct sched_context *con, int when, ast_sched_cb callback, const void *data) |
static int | iax2_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final) |
static int | iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen) |
static int | iax2_sendimage (struct ast_channel *c, struct ast_frame *img) |
static int | iax2_sendtext (struct ast_channel *c, const char *dest, const char *text, int ispdu) |
static int | iax2_setoption (struct ast_channel *c, int option, void *data, int datalen) |
static int | iax2_show_cache (int fd, int argc, char *argv[]) |
static int | iax2_show_channels (int fd, int argc, char *argv[]) |
static int | iax2_show_firmware (int fd, int argc, char *argv[]) |
static int | iax2_show_netstats (int fd, int argc, char *argv[]) |
static int | iax2_show_peer (int fd, int argc, char *argv[]) |
Show one peer in detail. | |
static int | iax2_show_peers (int fd, int argc, char *argv[]) |
static int | iax2_show_registry (int fd, int argc, char *argv[]) |
static int | iax2_show_stats (int fd, int argc, char *argv[]) |
static int | iax2_show_threads (int fd, int argc, char *argv[]) |
static int | iax2_show_users (int fd, int argc, char *argv[]) |
static int | iax2_start_transfer (unsigned short callno0, unsigned short callno1, int mediaonly) |
static int | iax2_test_losspct (int fd, int argc, char *argv[]) |
static int | iax2_transfer (struct ast_channel *c, const char *dest) |
static int | iax2_transmit (struct iax_frame *fr) |
static int | iax2_trunk_expired (struct iax2_trunk_peer *tpeer, struct timeval *now) |
static int | iax2_trunk_queue (struct chan_iax2_pvt *pvt, struct iax_frame *fr) |
static int | iax2_vnak (int callno) |
static int | iax2_write (struct ast_channel *c, struct ast_frame *f) |
static int | iax_check_version (char *dev) |
static void | iax_debug_output (const char *data) |
static void | iax_error_output (const char *data) |
static int | iax_firmware_append (struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc) |
static int | iax_park (struct ast_channel *chan1, struct ast_channel *chan2) |
static void * | iax_park_thread (void *stuff) |
static struct iax_frame * | iaxfrdup2 (struct iax_frame *fr) |
static void | insert_idle_thread (struct iax2_thread *thread) |
static void | jb_debug_output (const char *fmt,...) |
static void | jb_error_output (const char *fmt,...) |
static void | jb_warning_output (const char *fmt,...) |
static int | load_module (void) |
Load IAX2 module, load configuraiton ---. | |
static void | lock_both (unsigned short callno0, unsigned short callno1) |
static int | make_trunk (unsigned short callno, int locked) |
static int | manager_iax2_show_netstats (struct mansession *s, const struct message *m) |
static int | manager_iax2_show_peers (struct mansession *s, const struct message *m) |
static int | match (struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur, int full_frame) |
static void | memcpy_decrypt (unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx) |
static void | memcpy_encrypt (unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx) |
static void | merge_encryption (struct chan_iax2_pvt *p, unsigned int enc) |
static void * | network_thread (void *ignore) |
static struct chan_iax2_pvt * | new_iax (struct sockaddr_in *sin, const char *host) |
static void | parse_dial_string (char *data, struct parsed_dial_string *pds) |
Parses an IAX dial string into its component parts. | |
static int | peer_cmp_cb (void *obj, void *arg, int flags) |
static int | peer_delme_cb (void *obj, void *arg, int flags) |
static void | peer_destructor (void *obj) |
static int | peer_hash_cb (const void *obj, const int flags) |
static struct iax2_peer * | peer_ref (struct iax2_peer *peer) |
static int | peer_set_sock_cb (void *obj, void *arg, int flags) |
static int | peer_set_srcaddr (struct iax2_peer *peer, const char *srcaddr) |
Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found. | |
static int | peer_status (struct iax2_peer *peer, char *status, int statuslen) |
peer_status: Report Peer status in character string | |
static struct iax2_peer * | peer_unref (struct iax2_peer *peer) |
static void | poke_all_peers (void) |
static void | prune_peers (void) |
static void | prune_users (void) |
static int | raw_hangup (struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd) |
static struct iax2_peer * | realtime_peer (const char *peername, struct sockaddr_in *sin) |
static void | realtime_update_peer (const char *peername, struct sockaddr_in *sin, time_t regtime) |
static struct iax2_user * | realtime_user (const char *username, struct sockaddr_in *sin) |
static void | reg_source_db (struct iax2_peer *p) |
static void | register_peer_exten (struct iax2_peer *peer, int onoff) |
static int | register_verify (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
Verify inbound registration. | |
static int | registry_authrequest (int callno) |
static int | registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin) |
static char * | regstate2str (int regstate) |
static int | reload (void) |
static int | reload_config (void) |
static void | reload_firmware (int unload) |
static void | save_rr (struct iax_frame *fr, struct iax_ies *ies) |
static void * | sched_thread (void *ignore) |
static int | schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout) |
static int | send_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 int | timing_read (int *id, int fd, short events, void *cbdata) |
static int | transmit_trunk (struct iax_frame *f, struct sockaddr_in *sin, int sockfd) |
static int | try_firmware (char *s) |
static int | try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
static int | uncompress_subclass (unsigned char csub) |
static void | unlink_peer (struct iax2_peer *peer) |
static int | unload_module (void) |
static void | unlock_both (unsigned short callno0, unsigned short callno1) |
static void | unwrap_timestamp (struct iax_frame *fr) |
static void | update_jbsched (struct chan_iax2_pvt *pvt) |
static void | update_max_nontrunk (void) |
static void | update_max_trunk (void) |
static int | update_packet (struct iax_frame *f) |
static int | update_registry (struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh) |
static int | user_cmp_cb (void *obj, void *arg, int flags) |
static int | user_delme_cb (void *obj, void *arg, int flags) |
static void | user_destructor (void *obj) |
static int | user_hash_cb (const void *obj, const int flags) |
static struct iax2_user * | user_ref (struct iax2_user *user) |
static struct iax2_user * | user_unref (struct iax2_user *user) |
static void | vnak_retransmit (int callno, int last) |
Variables | |
static char | accountcode [AST_MAX_ACCOUNT_CODE] |
static int | adsi = 0 |
static int | amaflags = 0 |
static int | authdebug = 1 |
static int | autokill = 0 |
static struct ast_cli_entry | cli_iax2 [] |
static struct ast_cli_entry | cli_iax2_jb_debug_deprecated |
static struct ast_cli_entry | cli_iax2_no_debug_deprecated |
static struct ast_cli_entry | cli_iax2_no_jb_debug_deprecated |
static struct ast_cli_entry | cli_iax2_no_trunk_debug_deprecated |
static struct ast_cli_entry | cli_iax2_trunk_debug_deprecated |
static char | context [80] = "default" |
static char | debug_jb_usage [] |
static char | debug_trunk_usage [] |
static char | debug_usage [] |
static int | defaultsockfd = -1 |
static int | delayreject = 0 |
static struct iax2_dpcache * | dpcache |
static int | global_rtautoclear = 120 |
static struct ast_flags | globalflags = { 0 } |
static int | iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH |
static int | iax2_encryption = 0 |
enum { ... } | iax2_flags |
int(* | iax2_regfunk )(const char *username, int onoff) = NULL |
static char | iax2_reload_usage [] |
enum { ... } | iax2_state |
static struct ast_switch | iax2_switch |
static struct ast_channel_tech | iax2_tech |
static char | iax2_test_losspct_usage [] |
static int | iaxactivethreadcount = 0 |
static int | iaxcompat = 0 |
static int | iaxdebug = 0 |
static int | iaxdefaultdpcache = 10 * 60 |
static int | iaxdefaulttimeout = 5 |
static int | iaxdynamicthreadcount = 0 |
static int | iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT |
struct ast_custom_function | iaxpeer_function |
static struct ast_iax2_queue | iaxq |
static struct chan_iax2_pvt * | iaxs [IAX_MAX_CALLS] |
static ast_mutex_t | iaxsl [IAX_MAX_CALLS] |
static int | iaxthreadcount = DEFAULT_THREAD_COUNT |
static int | iaxtrunkdebug = 0 |
static struct io_context * | io |
static int | lagrq_time = 10 |
static char | language [MAX_LANGUAGE] = "" |
static int | last_authmethod = 0 |
static struct timeval | lastused [IAX_MAX_CALLS] |
static int | max_reg_expire |
static int | max_retries = 4 |
static int | maxauthreq = 3 |
static int | maxjitterbuffer = 1000 |
static int | maxjitterinterps = 10 |
static int | maxnontrunkcall = 1 |
static int | maxtrunkcall = TRUNK_CALL_START |
static int | min_reg_expire |
static char | mohinterpret [MAX_MUSICCLASS] |
static char | mohsuggest [MAX_MUSICCLASS] |
static struct ast_netsock_list * | netsock |
static pthread_t | netthreadid = AST_PTHREADT_NULL |
static char | no_debug_jb_usage [] |
static char | no_debug_trunk_usage [] |
static char | no_debug_usage [] |
static struct ast_netsock_list * | outsock |
static char * | papp = "IAX2Provision" |
static char * | pdescrip |
static struct ao2_container * | peers |
static int | ping_time = 21 |
static struct ast_codec_pref | prefs |
static char | prune_realtime_usage [] |
static char * | psyn = "Provision a calling IAXy with a given template" |
static char | regcontext [AST_MAX_CONTEXT] = "" |
static int | resyncthreshold = 1000 |
static struct sched_context * | sched |
static ast_cond_t | sched_cond |
static pthread_t | schedthreadid = AST_PTHREADT_NULL |
static char | show_cache_usage [] |
static char | show_channels_usage [] |
static char | show_firmware_usage [] |
static char | show_netstats_usage [] |
static char | show_peer_usage [] |
static char | show_peers_usage [] |
static char | show_prov_usage [] |
static char | show_reg_usage [] |
static char | show_stats_usage [] |
static char | show_threads_usage [] |
static char | show_users_usage [] |
static const char | tdesc [] = "Inter Asterisk eXchange Driver (Ver 2)" |
static int | test_losspct = 0 |
static int | timingfd = -1 |
static unsigned int | tos = 0 |
static struct iax2_trunk_peer * | tpeers |
static int | trunkfreq = 20 |
static struct ao2_container * | users |
static struct ast_firmware_list | waresl |
Definition in file chan_iax2.c.
#define CACHE_FLAG_CANEXIST (1 << 2) |
Extension can exist
Definition at line 669 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 665 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 679 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 667 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 671 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 673 of file chan_iax2.c.
Referenced by find_cache(), and iax2_show_cache().
#define CACHE_FLAG_TRANSMITTED (1 << 5) |
Request transmitted
Definition at line 675 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 677 of file chan_iax2.c.
Referenced by complete_dpreply(), and iax2_show_cache().
#define CALLNO_TO_PTR | ( | a | ) | ((void *)(unsigned long)(a)) |
Definition at line 126 of file chan_iax2.c.
Referenced by ast_iax2_new(), iax2_call(), and update_jbsched().
#define DEBUG_SCHED_MULTITHREAD |
Definition at line 114 of file chan_iax2.c.
#define DEBUG_SUPPORT |
Definition at line 137 of file chan_iax2.c.
#define DEFAULT_DROP 3 |
Definition at line 132 of file chan_iax2.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 205 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 204 of file chan_iax2.c.
Referenced by build_peer(), and handle_response_peerpoke().
#define DEFAULT_MAX_THREAD_COUNT 100 |
Definition at line 129 of file chan_iax2.c.
#define DEFAULT_MAXMS 2000 |
Definition at line 203 of file chan_iax2.c.
#define DEFAULT_RETRY_TIME 1000 |
#define DEFAULT_THREAD_COUNT 10 |
Definition at line 128 of file chan_iax2.c.
#define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 448 of file chan_iax2.c.
Referenced by iax2_trunk_queue().
#define FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s\n" |
#define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
#define FORMAT "%-15.15s %-15d %-15d\n" |
#define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" |
#define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
#define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" |
#define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
#define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" |
#define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" |
#define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
#define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
#define GAMMA (0.01) |
Definition at line 142 of file chan_iax2.c.
#define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
#define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
Definition at line 186 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 194 of file chan_iax2.c.
Referenced by set_config().
#define IAX_CAPABILITY_LOWFREE |
Value:
Definition at line 199 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 188 of file chan_iax2.c.
Referenced by set_config().
#define IAX_IOSTATE_IDLE 0 |
#define IAX_IOSTATE_PROCESSING 2 |
#define IAX_IOSTATE_READY 1 |
#define IAX_IOSTATE_SCHEDREADY 3 |
Definition at line 703 of file chan_iax2.c.
Referenced by __schedule_action(), and iax2_process_thread().
#define IAX_TYPE_DYNAMIC 2 |
Definition at line 706 of file chan_iax2.c.
Referenced by find_idle_thread(), iax2_process_thread(), iax2_show_threads(), and insert_idle_thread().
#define IAX_TYPE_POOL 1 |
#define IPTOS_MINCOST 0x02 |
Definition at line 117 of file chan_iax2.c.
#define MAX_JITTER_BUFFER 50 |
Definition at line 445 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 651 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 451 of file chan_iax2.c.
#define MAX_TRUNKDATA 640 * 200 |
40ms, uncompressed linear * 200 channels
Definition at line 449 of file chan_iax2.c.
Referenced by iax2_trunk_queue(), and timing_read().
#define MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define MEMORY_SIZE 100 |
Definition at line 131 of file chan_iax2.c.
#define MIN_JITTER_BUFFER 10 |
Definition at line 446 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 1243 of file chan_iax2.c.
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_poke_peer(), iax2_provision(), and iax2_request().
#define NEW_PREVENT 0 |
#define PTR_TO_CALLNO | ( | a | ) | ((unsigned short)(unsigned long)(a)) |
Definition at line 125 of file chan_iax2.c.
Referenced by __auto_congest(), __get_from_jb(), function_iaxpeer(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_digit_begin(), iax2_digit_end(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_prov_app(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), iax2_transfer(), and iax2_write().
#define SCHED_MULTITHREADED |
Definition at line 110 of file chan_iax2.c.
Definition at line 969 of file chan_iax2.c.
Referenced by attempt_transmit(), auth_reject(), auto_congest(), auto_hangup(), expire_registry(), get_from_jb(), iax2_do_register_s(), iax2_poke_noanswer(), iax2_poke_peer_s(), send_lagrq(), and send_ping().
#define TRUNK_CALL_START 0x4000 |
Definition at line 135 of file chan_iax2.c.
Referenced by find_callno(), make_trunk(), update_max_nontrunk(), and update_max_trunk().
#define TS_GAP_FOR_JB_RESYNC 5000 |
Definition at line 454 of file chan_iax2.c.
anonymous enum |
Definition at line 239 of file chan_iax2.c.
00239 { 00240 IAX_STATE_STARTED = (1 << 0), 00241 IAX_STATE_AUTHENTICATED = (1 << 1), 00242 IAX_STATE_TBD = (1 << 2), 00243 IAX_STATE_UNCHANGED = (1 << 3), 00244 } iax2_state;
anonymous enum |
Definition at line 251 of file chan_iax2.c.
00251 { 00252 IAX_HASCALLERID = (1 << 0), /*!< CallerID has been specified */ 00253 IAX_DELME = (1 << 1), /*!< Needs to be deleted */ 00254 IAX_TEMPONLY = (1 << 2), /*!< Temporary (realtime) */ 00255 IAX_TRUNK = (1 << 3), /*!< Treat as a trunk */ 00256 IAX_NOTRANSFER = (1 << 4), /*!< Don't native bridge */ 00257 IAX_USEJITTERBUF = (1 << 5), /*!< Use jitter buffer */ 00258 IAX_DYNAMIC = (1 << 6), /*!< dynamic peer */ 00259 IAX_SENDANI = (1 << 7), /*!< Send ANI along with CallerID */ 00260 /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */ 00261 IAX_ALREADYGONE = (1 << 9), /*!< Already disconnected */ 00262 IAX_PROVISION = (1 << 10), /*!< This is a provisioning request */ 00263 IAX_QUELCH = (1 << 11), /*!< Whether or not we quelch audio */ 00264 IAX_ENCRYPTED = (1 << 12), /*!< Whether we should assume encrypted tx/rx */ 00265 IAX_KEYPOPULATED = (1 << 13), /*!< Whether we have a key populated */ 00266 IAX_CODEC_USER_FIRST = (1 << 14), /*!< are we willing to let the other guy choose the codec? */ 00267 IAX_CODEC_NOPREFS = (1 << 15), /*!< Force old behaviour by turning off prefs */ 00268 IAX_CODEC_NOCAP = (1 << 16), /*!< only consider requested format and ignore capabilities*/ 00269 IAX_RTCACHEFRIENDS = (1 << 17), /*!< let realtime stay till your reload */ 00270 IAX_RTUPDATE = (1 << 18), /*!< Send a realtime update */ 00271 IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */ 00272 IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 00273 IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */ 00274 IAX_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */ 00275 IAX_TRANSFERMEDIA = (1 << 23), /*!< When doing IAX2 transfers, transfer media only */ 00276 IAX_MAXAUTHREQ = (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */ 00277 IAX_DELAYPBXSTART = (1 << 25), /*!< Don't start a PBX on the channel until the peer sends us a 00278 response, so that we've achieved a three-way handshake with 00279 them before sending voice or anything else*/ 00280 IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */ 00281 } 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 400 of file chan_iax2.c.
00400 { 00401 REG_STATE_UNREGISTERED = 0, 00402 REG_STATE_REGSENT, 00403 REG_STATE_AUTHSENT, 00404 REG_STATE_REGISTERED, 00405 REG_STATE_REJECTED, 00406 REG_STATE_TIMEOUT, 00407 REG_STATE_NOAUTH 00408 };
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 410 of file chan_iax2.c.
00410 { 00411 TRANSFER_NONE = 0, 00412 TRANSFER_BEGIN, 00413 TRANSFER_READY, 00414 TRANSFER_RELEASED, 00415 TRANSFER_PASSTHROUGH, 00416 TRANSFER_MBEGIN, 00417 TRANSFER_MREADY, 00418 TRANSFER_MRELEASED, 00419 TRANSFER_MPASSTHROUGH, 00420 TRANSFER_MEDIA, 00421 TRANSFER_MEDIAPASS 00422 };
static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 2060 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), attempt_transmit(), iax_frame::callno, iax2_registry::callno, chan_iax2_pvt::error, f, iax_frame::final, ast_frame::frametype, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), iax2_sched_add(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxq, iaxs, iaxsl, LOG_WARNING, MAX_RETRY_TIME, iax_frame::oseqno, chan_iax2_pvt::owner, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_command(), send_packet(), ast_frame::subclass, iax_frame::transfer, iax_frame::ts, update_packet(), and iax2_registry::us.
Referenced by attempt_transmit().
02061 { 02062 /* Attempt to transmit the frame to the remote peer... 02063 Called without iaxsl held. */ 02064 struct iax_frame *f = (struct iax_frame *)data; 02065 int freeme=0; 02066 int callno = f->callno; 02067 /* Make sure this call is still active */ 02068 if (callno) 02069 ast_mutex_lock(&iaxsl[callno]); 02070 if (callno && iaxs[callno]) { 02071 if ((f->retries < 0) /* Already ACK'd */ || 02072 (f->retries >= max_retries) /* Too many attempts */) { 02073 /* Record an error if we've transmitted too many times */ 02074 if (f->retries >= max_retries) { 02075 if (f->transfer) { 02076 /* Transfer timeout */ 02077 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 02078 } else if (f->final) { 02079 if (f->final) 02080 iax2_destroy(callno); 02081 } else { 02082 if (iaxs[callno]->owner) 02083 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); 02084 iaxs[callno]->error = ETIMEDOUT; 02085 if (iaxs[callno]->owner) { 02086 struct ast_frame fr = { 0, }; 02087 /* Hangup the fd */ 02088 fr.frametype = AST_FRAME_CONTROL; 02089 fr.subclass = AST_CONTROL_HANGUP; 02090 iax2_queue_frame(callno, &fr); // XXX 02091 /* Remember, owner could disappear */ 02092 if (iaxs[callno] && iaxs[callno]->owner) 02093 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 02094 } else { 02095 if (iaxs[callno]->reg) { 02096 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 02097 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 02098 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 02099 } 02100 iax2_destroy(callno); 02101 } 02102 } 02103 02104 } 02105 freeme++; 02106 } else { 02107 /* Update it if it needs it */ 02108 update_packet(f); 02109 /* Attempt transmission */ 02110 send_packet(f); 02111 f->retries++; 02112 /* Try again later after 10 times as long */ 02113 f->retrytime *= 10; 02114 if (f->retrytime > MAX_RETRY_TIME) 02115 f->retrytime = MAX_RETRY_TIME; 02116 /* Transfer messages max out at one second */ 02117 if (f->transfer && (f->retrytime > 1000)) 02118 f->retrytime = 1000; 02119 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 02120 } 02121 } else { 02122 /* Make sure it gets freed */ 02123 f->retries = -1; 02124 freeme++; 02125 } 02126 if (callno) 02127 ast_mutex_unlock(&iaxsl[callno]); 02128 /* Do not try again */ 02129 if (freeme) { 02130 /* Don't attempt delivery, just remove it from the queue */ 02131 AST_LIST_LOCK(&iaxq.queue); 02132 AST_LIST_REMOVE(&iaxq.queue, f, list); 02133 iaxq.count--; 02134 AST_LIST_UNLOCK(&iaxq.queue); 02135 f->retrans = -1; 02136 /* Free the IAX frame */ 02137 iax2_frame_free(f); 02138 } 02139 }
static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 6208 of file chan_iax2.c.
References AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_FACILITY_REJECTED, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax_ie_data::buf, iax2_registry::callno, IAX_COMMAND_REGREJ, IAX_COMMAND_REJECT, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, iax_ie_data::pos, and send_command_final().
Referenced by auth_reject().
06209 { 06210 /* Called from IAX thread only, without iaxs lock */ 06211 int callno = (int)(long)(nothing); 06212 struct iax_ie_data ied; 06213 ast_mutex_lock(&iaxsl[callno]); 06214 if (iaxs[callno]) { 06215 memset(&ied, 0, sizeof(ied)); 06216 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 06217 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 06218 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 06219 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 06220 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 06221 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 06222 } 06223 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 06224 } 06225 ast_mutex_unlock(&iaxsl[callno]); 06226 }
static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 3004 of file chan_iax2.c.
References AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_queue_frame(), iaxs, iaxsl, chan_iax2_pvt::initid, LOG_NOTICE, and PTR_TO_CALLNO.
Referenced by auto_congest().
03005 { 03006 int callno = PTR_TO_CALLNO(nothing); 03007 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 03008 ast_mutex_lock(&iaxsl[callno]); 03009 if (iaxs[callno]) { 03010 iaxs[callno]->initid = -1; 03011 iax2_queue_frame(callno, &f); 03012 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 03013 } 03014 ast_mutex_unlock(&iaxsl[callno]); 03015 }
static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 6258 of file chan_iax2.c.
References AST_CAUSE_NO_USER_RESPONSE, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax_ie_data::buf, iax2_registry::callno, IAX_COMMAND_HANGUP, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, iax_ie_data::pos, and send_command_final().
Referenced by auto_hangup().
06259 { 06260 /* Called from IAX thread only, without iaxs lock */ 06261 int callno = (int)(long)(nothing); 06262 struct iax_ie_data ied; 06263 ast_mutex_lock(&iaxsl[callno]); 06264 if (iaxs[callno]) { 06265 memset(&ied, 0, sizeof(ied)); 06266 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 06267 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 06268 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 06269 } 06270 ast_mutex_unlock(&iaxsl[callno]); 06271 }
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 1819 of file chan_iax2.c.
References iax_frame::af, ast_test_flag, iax_frame::callno, ast_frame::has_timing_info, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, and iax_frame::retrans.
Referenced by __get_from_jb(), and schedule_delivery().
01820 { 01821 /* Just deliver the packet by using queueing. This is called by 01822 the IAX thread with the iaxsl lock held. */ 01823 struct iax_frame *fr = data; 01824 fr->retrans = -1; 01825 fr->af.has_timing_info = 0; 01826 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 01827 iax2_queue_frame(fr->callno, &fr->af); 01828 /* Free our iax frame */ 01829 iax2_frame_free(fr); 01830 /* And don't run again */ 01831 return 0; 01832 }
static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 5890 of file chan_iax2.c.
References iax2_peer::addr, ast_db_del(), ast_device_state_changed(), ast_log(), ast_test_flag, EVENT_FLAG_SYSTEM, iax2_peer::expire, iax2_peer::expiry, iax2_regfunk, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_TEMPONLY, LOG_DEBUG, manager_event(), option_debug, peer_unref(), realtime_update_peer(), register_peer_exten(), and unlink_peer().
Referenced by expire_registry().
05891 { 05892 struct iax2_peer *peer = (struct iax2_peer *) data; 05893 05894 if (!peer) 05895 return; 05896 05897 peer->expire = -1; 05898 05899 if (option_debug) 05900 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name); 05901 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 05902 realtime_update_peer(peer->name, &peer->addr, 0); 05903 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 05904 /* Reset the address */ 05905 memset(&peer->addr, 0, sizeof(peer->addr)); 05906 /* Reset expiry value */ 05907 peer->expiry = min_reg_expire; 05908 if (!ast_test_flag(peer, IAX_TEMPONLY)) 05909 ast_db_del("IAX/Registry", peer->name); 05910 register_peer_exten(peer, 0); 05911 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 05912 if (iax2_regfunk) 05913 iax2_regfunk(peer->name, 0); 05914 05915 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) 05916 unlink_peer(peer); 05917 05918 peer_unref(peer); 05919 }
static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 2457 of file chan_iax2.c.
References __do_deliver(), ast_codec_interp_len(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_tvadd(), iax2_registry::callno, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, iaxsl, chan_iax2_pvt::jb, JB_DROP, JB_EMPTY, jb_get(), JB_INTERP, jb_next(), JB_NOFRAME, JB_OK, chan_iax2_pvt::jbid, jb_frame::ms, ast_frame::offset, PTR_TO_CALLNO, chan_iax2_pvt::rxcore, ast_frame::samples, ast_frame::src, ast_frame::subclass, update_jbsched(), and chan_iax2_pvt::voiceformat.
Referenced by get_from_jb().
02458 { 02459 int callno = PTR_TO_CALLNO(p); 02460 struct chan_iax2_pvt *pvt = NULL; 02461 struct iax_frame *fr; 02462 jb_frame frame; 02463 int ret; 02464 long now; 02465 long next; 02466 struct timeval tv; 02467 02468 /* Make sure we have a valid private structure before going on */ 02469 ast_mutex_lock(&iaxsl[callno]); 02470 pvt = iaxs[callno]; 02471 if (!pvt) { 02472 /* No go! */ 02473 ast_mutex_unlock(&iaxsl[callno]); 02474 return; 02475 } 02476 02477 pvt->jbid = -1; 02478 02479 gettimeofday(&tv,NULL); 02480 /* round up a millisecond since ast_sched_runq does; */ 02481 /* prevents us from spinning while waiting for our now */ 02482 /* to catch up with runq's now */ 02483 tv.tv_usec += 1000; 02484 02485 now = ast_tvdiff_ms(tv, pvt->rxcore); 02486 02487 if(now >= (next = jb_next(pvt->jb))) { 02488 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat)); 02489 switch(ret) { 02490 case JB_OK: 02491 fr = frame.data; 02492 __do_deliver(fr); 02493 /* __do_deliver() can cause the call to disappear */ 02494 pvt = iaxs[callno]; 02495 break; 02496 case JB_INTERP: 02497 { 02498 struct ast_frame af = { 0, }; 02499 02500 /* create an interpolation frame */ 02501 af.frametype = AST_FRAME_VOICE; 02502 af.subclass = pvt->voiceformat; 02503 af.samples = frame.ms * 8; 02504 af.src = "IAX2 JB interpolation"; 02505 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 02506 af.offset = AST_FRIENDLY_OFFSET; 02507 02508 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 02509 * which we'd need to malloc, and then it would free it. That seems like a drag */ 02510 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) { 02511 iax2_queue_frame(callno, &af); 02512 /* iax2_queue_frame() could cause the call to disappear */ 02513 pvt = iaxs[callno]; 02514 } 02515 } 02516 break; 02517 case JB_DROP: 02518 iax2_frame_free(frame.data); 02519 break; 02520 case JB_NOFRAME: 02521 case JB_EMPTY: 02522 /* do nothing */ 02523 break; 02524 default: 02525 /* shouldn't happen */ 02526 break; 02527 } 02528 } 02529 if (pvt) 02530 update_jbsched(pvt); 02531 ast_mutex_unlock(&iaxsl[callno]); 02532 }
static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 5588 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
05589 { 05590 struct iax2_registry *reg = (struct iax2_registry *)data; 05591 reg->expire = -1; 05592 iax2_do_register(reg); 05593 }
static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 8649 of file chan_iax2.c.
References ast_device_state_changed(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_peer::callno, EVENT_FLAG_SYSTEM, iax2_destroy(), iax2_poke_peer_s(), iax2_sched_add(), iaxsl, iax2_peer::lastms, LOG_NOTICE, manager_event(), peer_ref(), peer_unref(), iax2_peer::pokeexpire, and iax2_peer::pokefreqnotok.
Referenced by iax2_poke_noanswer().
08650 { 08651 struct iax2_peer *peer = (struct iax2_peer *)data; 08652 if (peer->lastms > -1) { 08653 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 08654 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 08655 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 08656 } 08657 if (peer->callno > 0) { 08658 ast_mutex_lock(&iaxsl[peer->callno]); 08659 iax2_destroy(peer->callno); 08660 ast_mutex_unlock(&iaxsl[peer->callno]); 08661 } 08662 peer->callno = 0; 08663 peer->lastms = -1; 08664 /* Try again quickly */ 08665 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 08666 if (peer->pokeexpire == -1) 08667 peer_unref(peer); 08668 }
static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 6322 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
06323 { 06324 struct iax2_peer *peer = (struct iax2_peer *)data; 06325 iax2_poke_peer(peer, 0); 06326 peer_unref(peer); 06327 }
static int __iax2_show_peers | ( | int | manager, | |
int | fd, | |||
struct mansession * | s, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4372 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), ast_cli(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_append(), iax2_peer::encmethods, FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, name, peer_status(), peer_unref(), peers, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
Referenced by iax2_show_peers(), and manager_iax2_show_peers().
04373 { 04374 regex_t regexbuf; 04375 int havepattern = 0; 04376 int total_peers = 0; 04377 int online_peers = 0; 04378 int offline_peers = 0; 04379 int unmonitored_peers = 0; 04380 struct ao2_iterator i; 04381 04382 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 04383 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 04384 04385 struct iax2_peer *peer = NULL; 04386 char name[256]; 04387 int registeredonly=0; 04388 char *term = manager ? "\r\n" : "\n"; 04389 04390 switch (argc) { 04391 case 6: 04392 if (!strcasecmp(argv[3], "registered")) 04393 registeredonly = 1; 04394 else 04395 return RESULT_SHOWUSAGE; 04396 if (!strcasecmp(argv[4], "like")) { 04397 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 04398 return RESULT_SHOWUSAGE; 04399 havepattern = 1; 04400 } else 04401 return RESULT_SHOWUSAGE; 04402 break; 04403 case 5: 04404 if (!strcasecmp(argv[3], "like")) { 04405 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04406 return RESULT_SHOWUSAGE; 04407 havepattern = 1; 04408 } else 04409 return RESULT_SHOWUSAGE; 04410 break; 04411 case 4: 04412 if (!strcasecmp(argv[3], "registered")) 04413 registeredonly = 1; 04414 else 04415 return RESULT_SHOWUSAGE; 04416 break; 04417 case 3: 04418 break; 04419 default: 04420 return RESULT_SHOWUSAGE; 04421 } 04422 04423 04424 if (s) 04425 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04426 else 04427 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04428 04429 i = ao2_iterator_init(peers, 0); 04430 for (peer = ao2_iterator_next(&i); peer; 04431 peer_unref(peer), peer = ao2_iterator_next(&i)) { 04432 char nm[20]; 04433 char status[20]; 04434 char srch[2000]; 04435 int retstatus; 04436 04437 if (registeredonly && !peer->addr.sin_addr.s_addr) 04438 continue; 04439 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 04440 continue; 04441 04442 if (!ast_strlen_zero(peer->username)) 04443 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 04444 else 04445 ast_copy_string(name, peer->name, sizeof(name)); 04446 04447 retstatus = peer_status(peer, status, sizeof(status)); 04448 if (retstatus > 0) 04449 online_peers++; 04450 else if (!retstatus) 04451 offline_peers++; 04452 else 04453 unmonitored_peers++; 04454 04455 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 04456 04457 snprintf(srch, sizeof(srch), FORMAT, name, 04458 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04459 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04460 nm, 04461 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04462 peer->encmethods ? "(E)" : " ", status, term); 04463 04464 if (s) 04465 astman_append(s, FORMAT, name, 04466 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)", 04467 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04468 nm, 04469 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04470 peer->encmethods ? "(E)" : " ", status, term); 04471 else 04472 ast_cli(fd, FORMAT, name, 04473 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04474 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04475 nm, 04476 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04477 peer->encmethods ? "(E)" : " ", status, term); 04478 total_peers++; 04479 } 04480 04481 if (s) 04482 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04483 else 04484 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04485 04486 if (havepattern) 04487 regfree(®exbuf); 04488 04489 return RESULT_SUCCESS; 04490 #undef FORMAT 04491 #undef FORMAT2 04492 }
static int __schedule_action | ( | void(*)(const void *data) | func, | |
const void * | data, | |||
const char * | funcname | |||
) | [static] |
Definition at line 944 of file chan_iax2.c.
References ast_log(), find_idle_thread(), func, IAX_IOSTATE_SCHEDREADY, LOG_NOTICE, signal_condition(), t, and thread.
00945 { 00946 struct iax2_thread *thread = NULL; 00947 static time_t lasterror; 00948 static time_t t; 00949 00950 thread = find_idle_thread(); 00951 00952 if (thread != NULL) { 00953 thread->schedfunc = func; 00954 thread->scheddata = data; 00955 thread->iostate = IAX_IOSTATE_SCHEDREADY; 00956 #ifdef DEBUG_SCHED_MULTITHREAD 00957 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 00958 #endif 00959 signal_condition(&thread->lock, &thread->cond); 00960 return 0; 00961 } 00962 time(&t); 00963 if (t != lasterror) 00964 ast_log(LOG_NOTICE, "Out of idle IAX2 threads for scheduling!\n"); 00965 lasterror = t; 00966 00967 return -1; 00968 }
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 4873 of file chan_iax2.c.
References ast_frame::data, ast_frame::datalen, ast_frame::frametype, iax2_send(), ast_frame::src, and ast_frame::subclass.
Referenced by send_command(), send_command_final(), send_command_immediate(), and send_command_transfer().
04875 { 04876 struct ast_frame f = { 0, }; 04877 04878 f.frametype = type; 04879 f.subclass = command; 04880 f.datalen = datalen; 04881 f.src = __FUNCTION__; 04882 f.data = (void *) data; 04883 04884 return iax2_send(i, &f, ts, seqno, now, transfer, final); 04885 }
static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1018 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_sched_add(), IAX_COMMAND_LAGRQ, iaxs, iaxsl, chan_iax2_pvt::lagid, send_command(), and send_lagrq().
Referenced by send_lagrq().
01019 { 01020 int callno = (long)data; 01021 /* Ping only if it's real not if it's bridged */ 01022 ast_mutex_lock(&iaxsl[callno]); 01023 if (iaxs[callno] && iaxs[callno]->lagid != -1) { 01024 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01025 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01026 } 01027 ast_mutex_unlock(&iaxsl[callno]); 01028 }
static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 984 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_sched_add(), IAX_COMMAND_PING, iaxs, iaxsl, chan_iax2_pvt::pingid, send_command(), and send_ping().
Referenced by send_ping().
00985 { 00986 int callno = (long)data; 00987 ast_mutex_lock(&iaxsl[callno]); 00988 if (iaxs[callno] && iaxs[callno]->pingid != -1) { 00989 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 00990 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 00991 } 00992 ast_mutex_unlock(&iaxsl[callno]); 00993 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 10766 of file chan_iax2.c.
References ao2_ref(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_cond_signal(), AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_manager_unregister(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_netsock_release(), AST_PTHREADT_NULL, ast_unregister_application(), ast_unregister_switch(), cli_iax2, delete_users(), iax2_destroy(), iax2_switch, iax2_tech, IAX_MAX_CALLS, iax_provision_unload(), iaxactivethreadcount, iaxq, iaxs, iaxsl, ast_firmware_list::lock, papp, peers, reload_firmware(), sched_context_destroy(), thread, users, and waresl.
Referenced by load_module(), and unload_module().
10767 { 10768 struct iax2_thread *thread = NULL; 10769 int x; 10770 10771 /* Make sure threads do not hold shared resources when they are canceled */ 10772 10773 /* Grab the sched lock resource to keep it away from threads about to die */ 10774 /* Cancel the network thread, close the net socket */ 10775 if (netthreadid != AST_PTHREADT_NULL) { 10776 AST_LIST_LOCK(&iaxq.queue); 10777 ast_mutex_lock(&sched_lock); 10778 pthread_cancel(netthreadid); 10779 ast_cond_signal(&sched_cond); 10780 ast_mutex_unlock(&sched_lock); /* Release the schedule lock resource */ 10781 AST_LIST_UNLOCK(&iaxq.queue); 10782 pthread_join(netthreadid, NULL); 10783 } 10784 if (schedthreadid != AST_PTHREADT_NULL) { 10785 ast_mutex_lock(&sched_lock); 10786 pthread_cancel(schedthreadid); 10787 ast_cond_signal(&sched_cond); 10788 ast_mutex_unlock(&sched_lock); 10789 pthread_join(schedthreadid, NULL); 10790 } 10791 10792 /* Call for all threads to halt */ 10793 AST_LIST_LOCK(&idle_list); 10794 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) { 10795 AST_LIST_REMOVE_CURRENT(&idle_list, list); 10796 pthread_cancel(thread->threadid); 10797 } 10798 AST_LIST_TRAVERSE_SAFE_END 10799 AST_LIST_UNLOCK(&idle_list); 10800 10801 AST_LIST_LOCK(&active_list); 10802 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) { 10803 AST_LIST_REMOVE_CURRENT(&active_list, list); 10804 pthread_cancel(thread->threadid); 10805 } 10806 AST_LIST_TRAVERSE_SAFE_END 10807 AST_LIST_UNLOCK(&active_list); 10808 10809 AST_LIST_LOCK(&dynamic_list); 10810 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) { 10811 AST_LIST_REMOVE_CURRENT(&dynamic_list, list); 10812 pthread_cancel(thread->threadid); 10813 } 10814 AST_LIST_TRAVERSE_SAFE_END 10815 AST_LIST_UNLOCK(&dynamic_list); 10816 10817 AST_LIST_HEAD_DESTROY(&iaxq.queue); 10818 10819 /* Wait for threads to exit */ 10820 while(0 < iaxactivethreadcount) 10821 usleep(10000); 10822 10823 ast_netsock_release(netsock); 10824 ast_netsock_release(outsock); 10825 for (x=0;x<IAX_MAX_CALLS;x++) 10826 if (iaxs[x]) 10827 iax2_destroy(x); 10828 ast_manager_unregister( "IAXpeers" ); 10829 ast_manager_unregister( "IAXnetstats" ); 10830 ast_unregister_application(papp); 10831 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 10832 ast_unregister_switch(&iax2_switch); 10833 ast_channel_unregister(&iax2_tech); 10834 delete_users(); 10835 iax_provision_unload(); 10836 sched_context_destroy(sched); 10837 reload_firmware(1); 10838 10839 ast_mutex_destroy(&waresl.lock); 10840 10841 for (x = 0; x < IAX_MAX_CALLS; x++) 10842 ast_mutex_destroy(&iaxsl[x]); 10843 10844 ao2_ref(peers, -1); 10845 ao2_ref(users, -1); 10846 10847 return 0; 10848 }
static int apply_context | ( | struct iax2_context * | con, | |
const char * | context | |||
) | [static] |
Definition at line 4926 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
04927 { 04928 while(con) { 04929 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 04930 return -1; 04931 con = con->next; 04932 } 04933 return 0; 04934 }
static int ast_cli_netstats | ( | struct mansession * | s, | |
int | fd, | |||
int | limit_fmt | |||
) | [static] |
Definition at line 4700 of file chan_iax2.c.
References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, astman_append(), jb_info::current, iax_rr::delay, iax_rr::dropped, fmt, jb_info::frames_dropped, jb_info::frames_lost, jb_info::frames_ooo, chan_iax2_pvt::frames_received, IAX_MAX_CALLS, IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), iax_rr::jitter, jb_info::jitter, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, jb_info::min, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::pingtime, and chan_iax2_pvt::remote_rr.
Referenced by iax2_show_netstats(), and manager_iax2_show_netstats().
04701 { 04702 int x; 04703 int numchans = 0; 04704 for (x=0;x<IAX_MAX_CALLS;x++) { 04705 ast_mutex_lock(&iaxsl[x]); 04706 if (iaxs[x]) { 04707 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 04708 char *fmt; 04709 jb_info jbinfo; 04710 04711 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04712 jb_getinfo(iaxs[x]->jb, &jbinfo); 04713 localjitter = jbinfo.jitter; 04714 localdelay = jbinfo.current - jbinfo.min; 04715 locallost = jbinfo.frames_lost; 04716 locallosspct = jbinfo.losspct/1000; 04717 localdropped = jbinfo.frames_dropped; 04718 localooo = jbinfo.frames_ooo; 04719 } else { 04720 localjitter = -1; 04721 localdelay = 0; 04722 locallost = -1; 04723 locallosspct = -1; 04724 localdropped = 0; 04725 localooo = -1; 04726 } 04727 if (limit_fmt) 04728 fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n"; 04729 else 04730 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"; 04731 if (s) 04732 04733 astman_append(s, fmt, 04734 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04735 iaxs[x]->pingtime, 04736 localjitter, 04737 localdelay, 04738 locallost, 04739 locallosspct, 04740 localdropped, 04741 localooo, 04742 iaxs[x]->frames_received/1000, 04743 iaxs[x]->remote_rr.jitter, 04744 iaxs[x]->remote_rr.delay, 04745 iaxs[x]->remote_rr.losscnt, 04746 iaxs[x]->remote_rr.losspct, 04747 iaxs[x]->remote_rr.dropped, 04748 iaxs[x]->remote_rr.ooo, 04749 iaxs[x]->remote_rr.packets/1000); 04750 else 04751 ast_cli(fd, fmt, 04752 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04753 iaxs[x]->pingtime, 04754 localjitter, 04755 localdelay, 04756 locallost, 04757 locallosspct, 04758 localdropped, 04759 localooo, 04760 iaxs[x]->frames_received/1000, 04761 iaxs[x]->remote_rr.jitter, 04762 iaxs[x]->remote_rr.delay, 04763 iaxs[x]->remote_rr.losscnt, 04764 iaxs[x]->remote_rr.losspct, 04765 iaxs[x]->remote_rr.dropped, 04766 iaxs[x]->remote_rr.ooo, 04767 iaxs[x]->remote_rr.packets/1000 04768 ); 04769 numchans++; 04770 } 04771 ast_mutex_unlock(&iaxsl[x]); 04772 } 04773 return numchans; 04774 }
static struct ast_channel* ast_iax2_new | ( | int | callno, | |
int | state, | |||
int | capability | |||
) | [static, read] |
Create new call, interface with the PBX core.
Definition at line 3608 of file chan_iax2.c.
References chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_channel_alloc(), ast_hangup(), ast_log(), ast_module_ref(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), AST_STATE_DOWN, ast_strdup, ast_string_field_set, ast_strlen_zero(), chan_iax2_pvt::calling_pres, chan_iax2_pvt::calling_tns, chan_iax2_pvt::calling_ton, chan_iax2_pvt::callno, CALLNO_TO_PTR, chan_iax2_pvt::capability, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, ast_channel::exten, iax2_tech, iaxs, iaxsl, LOG_WARNING, ast_variable::name, ast_channel::nativeformats, ast_variable::next, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), chan_iax2_pvt::peeradsicpe, ast_channel::readformat, ast_channel::tech, ast_channel::tech_pvt, ast_variable::value, chan_iax2_pvt::vars, and ast_channel::writeformat.
Referenced by iax2_request(), and socket_process().
03609 { 03610 struct ast_channel *tmp; 03611 struct chan_iax2_pvt *i; 03612 struct ast_variable *v = NULL; 03613 03614 if (!(i = iaxs[callno])) { 03615 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 03616 return NULL; 03617 } 03618 03619 /* Don't hold call lock */ 03620 ast_mutex_unlock(&iaxsl[callno]); 03621 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); 03622 ast_mutex_lock(&iaxsl[callno]); 03623 if (!tmp) 03624 return NULL; 03625 tmp->tech = &iax2_tech; 03626 /* We can support any format by default, until we get restricted */ 03627 tmp->nativeformats = capability; 03628 tmp->readformat = ast_best_codec(capability); 03629 tmp->writeformat = ast_best_codec(capability); 03630 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 03631 03632 /* Don't use ast_set_callerid() here because it will 03633 * generate a NewCallerID event before the NewChannel event */ 03634 if (!ast_strlen_zero(i->ani)) 03635 tmp->cid.cid_ani = ast_strdup(i->ani); 03636 else 03637 tmp->cid.cid_ani = ast_strdup(i->cid_num); 03638 tmp->cid.cid_dnid = ast_strdup(i->dnid); 03639 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 03640 tmp->cid.cid_pres = i->calling_pres; 03641 tmp->cid.cid_ton = i->calling_ton; 03642 tmp->cid.cid_tns = i->calling_tns; 03643 if (!ast_strlen_zero(i->language)) 03644 ast_string_field_set(tmp, language, i->language); 03645 if (!ast_strlen_zero(i->accountcode)) 03646 ast_string_field_set(tmp, accountcode, i->accountcode); 03647 if (i->amaflags) 03648 tmp->amaflags = i->amaflags; 03649 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 03650 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 03651 if (i->adsi) 03652 tmp->adsicpe = i->peeradsicpe; 03653 else 03654 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 03655 i->owner = tmp; 03656 i->capability = capability; 03657 03658 for (v = i->vars ; v ; v = v->next) 03659 pbx_builtin_setvar_helper(tmp, v->name, v->value); 03660 03661 if (state != AST_STATE_DOWN) { 03662 if (ast_pbx_start(tmp)) { 03663 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 03664 ast_hangup(tmp); 03665 i->owner = NULL; 03666 return NULL; 03667 } 03668 } 03669 03670 ast_module_ref(ast_module_info->self); 03671 03672 return tmp; 03673 }
static AST_LIST_HEAD_STATIC | ( | dynamic_list | , | |
iax2_thread | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | active_list | , | |
iax2_thread | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | idle_list | , | |
iax2_thread | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | registrations | , | |
iax2_registry | ||||
) | [static] |
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_DEFAULT | , | |||
"Inter Asterisk eXchange (Ver 2)" | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | reload = reload | |||
) |
AST_MUTEX_DEFINE_STATIC | ( | dpcache_lock | ) |
AST_MUTEX_DEFINE_STATIC | ( | tpeerlock | ) |
AST_MUTEX_DEFINE_STATIC | ( | sched_lock | ) |
static int attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 2141 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and network_thread().
02142 { 02143 #ifdef SCHED_MULTITHREADED 02144 if (schedule_action(__attempt_transmit, data)) 02145 #endif 02146 __attempt_transmit(data); 02147 return 0; 02148 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 6242 of file chan_iax2.c.
References ast_sched_del(), auth_reject(), chan_iax2_pvt::authfail, chan_iax2_pvt::authid, iax2_sched_add(), and iaxs.
Referenced by socket_process().
06243 { 06244 /* Schedule sending the authentication failure in one second, to prevent 06245 guessing */ 06246 if (iaxs[callno]) { 06247 iaxs[callno]->authfail = failcode; 06248 if (delayreject) { 06249 if (iaxs[callno]->authid > -1) 06250 ast_sched_del(sched, iaxs[callno]->authid); 06251 iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno); 06252 } else 06253 auth_reject((void *)(long)callno); 06254 } 06255 return 0; 06256 }
static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 6228 of file chan_iax2.c.
References __auth_reject(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::authid, iax2_registry::callno, iaxs, iaxsl, and schedule_action.
Referenced by auth_fail().
06229 { 06230 int callno = (int)(long)(data); 06231 ast_mutex_lock(&iaxsl[callno]); 06232 if (iaxs[callno]) 06233 iaxs[callno]->authid = -1; 06234 ast_mutex_unlock(&iaxsl[callno]); 06235 #ifdef SCHED_MULTITHREADED 06236 if (schedule_action(__auth_reject, data)) 06237 #endif 06238 __auth_reject(data); 06239 return 0; 06240 }
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 5457 of file chan_iax2.c.
References ast_inet_ntoa(), ast_key_get, AST_KEY_PRIVATE, ast_log(), ast_sign, ast_strlen_zero(), build_enc_keys(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, iax_ie_append_str(), IAX_IE_MD5_RESULT, IAX_IE_PASSWORD, IAX_IE_RSA_RESULT, key(), LOG_NOTICE, MD5Final(), MD5Init(), and MD5Update().
05458 { 05459 int res = -1; 05460 int x; 05461 if (!ast_strlen_zero(keyn)) { 05462 if (!(authmethods & IAX_AUTH_RSA)) { 05463 if (ast_strlen_zero(secret)) 05464 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)); 05465 } else if (ast_strlen_zero(challenge)) { 05466 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 05467 } else { 05468 char sig[256]; 05469 struct ast_key *key; 05470 key = ast_key_get(keyn, AST_KEY_PRIVATE); 05471 if (!key) { 05472 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 05473 } else { 05474 if (ast_sign(key, (char*)challenge, sig)) { 05475 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 05476 res = -1; 05477 } else { 05478 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 05479 res = 0; 05480 } 05481 } 05482 } 05483 } 05484 /* Fall back */ 05485 if (res && !ast_strlen_zero(secret)) { 05486 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 05487 struct MD5Context md5; 05488 unsigned char digest[16]; 05489 char digres[128]; 05490 MD5Init(&md5); 05491 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 05492 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 05493 MD5Final(digest, &md5); 05494 /* If they support md5, authenticate with it. */ 05495 for (x=0;x<16;x++) 05496 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 05497 if (ecx && dcx) 05498 build_enc_keys(digest, ecx, dcx); 05499 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 05500 res = 0; 05501 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 05502 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 05503 res = 0; 05504 } else 05505 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 05506 } 05507 return res; 05508 }
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 5514 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), authenticate(), iax_ies::authmethods, iax2_peer::authmethods, iax_ie_data::buf, chan_iax2_pvt::callno, iax2_registry::callno, iax_ies::challenge, chan_iax2_pvt::dcx, chan_iax2_pvt::ecx, chan_iax2_pvt::encmethods, iax_ies::encmethods, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_KEYPOPULATED, iaxs, iaxsl, iax2_peer::mask, merge_encryption(), peer_unref(), peers, iax_ie_data::pos, realtime_peer(), send_command(), and iax_ies::username.
Referenced by socket_process().
05515 { 05516 struct iax2_peer *peer = NULL; 05517 /* Start pessimistic */ 05518 int res = -1; 05519 int authmethods = 0; 05520 struct iax_ie_data ied; 05521 uint16_t callno = p->callno; 05522 05523 memset(&ied, 0, sizeof(ied)); 05524 05525 if (ies->username) 05526 ast_string_field_set(p, username, ies->username); 05527 if (ies->challenge) 05528 ast_string_field_set(p, challenge, ies->challenge); 05529 if (ies->authmethods) 05530 authmethods = ies->authmethods; 05531 if (authmethods & IAX_AUTH_MD5) 05532 merge_encryption(p, ies->encmethods); 05533 else 05534 p->encmethods = 0; 05535 05536 /* Check for override RSA authentication first */ 05537 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 05538 /* Normal password authentication */ 05539 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05540 } else { 05541 struct ao2_iterator i = ao2_iterator_init(peers, 0); 05542 while ((peer = ao2_iterator_next(&i))) { 05543 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 05544 /* No peer specified at our end, or this is the peer */ 05545 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 05546 /* No username specified in peer rule, or this is the right username */ 05547 && (!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))) 05548 /* No specified host, or this is our host */ 05549 ) { 05550 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05551 if (!res) { 05552 peer_unref(peer); 05553 break; 05554 } 05555 } 05556 peer_unref(peer); 05557 } 05558 if (!peer) { 05559 /* We checked our list and didn't find one. It's unlikely, but possible, 05560 that we're trying to authenticate *to* a realtime peer */ 05561 const char *peer_name = ast_strdupa(p->peer); 05562 ast_mutex_unlock(&iaxsl[callno]); 05563 if ((peer = realtime_peer(peer_name, NULL))) { 05564 ast_mutex_lock(&iaxsl[callno]); 05565 if (!(p = iaxs[callno])) { 05566 peer_unref(peer); 05567 return -1; 05568 } 05569 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05570 peer_unref(peer); 05571 } 05572 if (!peer) { 05573 ast_mutex_lock(&iaxsl[callno]); 05574 if (!(p = iaxs[callno])) 05575 return -1; 05576 } 05577 } 05578 } 05579 if (ies->encmethods) 05580 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 05581 if (!res) 05582 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 05583 return res; 05584 }
static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 5186 of file chan_iax2.c.
References ao2_find(), AST_CAUSE_CALL_REJECTED, AST_FRAME_IAX, ast_random(), ast_set_flag, ast_string_field_set, ast_test_flag, chan_iax2_pvt::authmethods, iax_ie_data::buf, iax2_user::curauthreq, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_COMMAND_AUTHREQ, IAX_COMMAND_REJECT, IAX_ENCRYPTED, iax_ie_append_byte(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_CHALLENGE, IAX_IE_ENCRYPTION, IAX_IE_USERNAME, IAX_MAXAUTHREQ, iaxs, iax2_user::maxauthreq, iax_ie_data::pos, send_command(), send_command_final(), user_unref(), and users.
Referenced by socket_process().
05187 { 05188 struct iax_ie_data ied; 05189 int res = -1, authreq_restrict = 0; 05190 char challenge[10]; 05191 struct chan_iax2_pvt *p = iaxs[call_num]; 05192 05193 memset(&ied, 0, sizeof(ied)); 05194 05195 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 05196 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05197 struct iax2_user *user, tmp_user = { 05198 .name = p->username, 05199 }; 05200 05201 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05202 if (user) { 05203 if (user->curauthreq == user->maxauthreq) 05204 authreq_restrict = 1; 05205 else 05206 user->curauthreq++; 05207 user = user_unref(user); 05208 } 05209 } 05210 05211 /* If the AUTHREQ limit test failed, send back an error */ 05212 if (authreq_restrict) { 05213 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 05214 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 05215 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 05216 return 0; 05217 } 05218 05219 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 05220 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 05221 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 05222 ast_string_field_set(p, challenge, challenge); 05223 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 05224 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 05225 } 05226 if (p->encmethods) 05227 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 05228 05229 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 05230 05231 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 05232 05233 if (p->encmethods) 05234 ast_set_flag(p, IAX_ENCRYPTED); 05235 05236 return res; 05237 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5239 of file chan_iax2.c.
References ao2_find(), ast_check_signature, ast_clear_flag, ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, chan_iax2_pvt::authmethods, iax2_user::curauthreq, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, key(), LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax_ies::password, iax_ies::rsa_result, iax2_registry::secret, chan_iax2_pvt::state, strsep(), user_unref(), and users.
Referenced by socket_process().
05240 { 05241 char requeststr[256]; 05242 char md5secret[256] = ""; 05243 char secret[256] = ""; 05244 char rsasecret[256] = ""; 05245 int res = -1; 05246 int x; 05247 struct iax2_user *user, tmp_user = { 05248 .name = p->username, 05249 }; 05250 05251 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05252 if (user) { 05253 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05254 ast_atomic_fetchadd_int(&user->curauthreq, -1); 05255 ast_clear_flag(p, IAX_MAXAUTHREQ); 05256 } 05257 ast_string_field_set(p, host, user->name); 05258 user = user_unref(user); 05259 } 05260 05261 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 05262 return res; 05263 if (ies->password) 05264 ast_copy_string(secret, ies->password, sizeof(secret)); 05265 if (ies->md5_result) 05266 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05267 if (ies->rsa_result) 05268 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05269 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 05270 struct ast_key *key; 05271 char *keyn; 05272 char tmpkey[256]; 05273 char *stringp=NULL; 05274 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 05275 stringp=tmpkey; 05276 keyn = strsep(&stringp, ":"); 05277 while(keyn) { 05278 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05279 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 05280 res = 0; 05281 break; 05282 } else if (!key) 05283 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 05284 keyn = strsep(&stringp, ":"); 05285 } 05286 } else if (p->authmethods & IAX_AUTH_MD5) { 05287 struct MD5Context md5; 05288 unsigned char digest[16]; 05289 char *tmppw, *stringp; 05290 05291 tmppw = ast_strdupa(p->secret); 05292 stringp = tmppw; 05293 while((tmppw = strsep(&stringp, ";"))) { 05294 MD5Init(&md5); 05295 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 05296 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05297 MD5Final(digest, &md5); 05298 /* If they support md5, authenticate with it. */ 05299 for (x=0;x<16;x++) 05300 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05301 if (!strcasecmp(requeststr, md5secret)) { 05302 res = 0; 05303 break; 05304 } 05305 } 05306 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 05307 if (!strcmp(secret, p->secret)) 05308 res = 0; 05309 } 05310 return res; 05311 }
static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 3017 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), and sip_call().
03018 { 03019 #ifdef SCHED_MULTITHREADED 03020 if (schedule_action(__auto_congest, data)) 03021 #endif 03022 __auto_congest(data); 03023 return 0; 03024 }
static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 6273 of file chan_iax2.c.
References __auto_hangup(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::autoid, iax2_registry::callno, iaxs, iaxsl, and schedule_action.
Referenced by iax2_dprequest(), and iax2_provision().
06274 { 06275 int callno = (int)(long)(data); 06276 ast_mutex_lock(&iaxsl[callno]); 06277 if (iaxs[callno]) { 06278 iaxs[callno]->autoid = -1; 06279 } 06280 ast_mutex_unlock(&iaxsl[callno]); 06281 #ifdef SCHED_MULTITHREADED 06282 if (schedule_action(__auto_hangup, data)) 06283 #endif 06284 __auto_hangup(data); 06285 return 0; 06286 }
static struct iax2_context* build_context | ( | char * | context | ) | [static, read] |
Definition at line 8964 of file chan_iax2.c.
References ast_calloc, and iax2_context::context.
Referenced by build_user().
08965 { 08966 struct iax2_context *con; 08967 08968 if ((con = ast_calloc(1, sizeof(*con)))) 08969 ast_copy_string(con->context, context, sizeof(con->context)); 08970 08971 return con; 08972 }
static void build_enc_keys | ( | const unsigned char * | digest, | |
aes_encrypt_ctx * | ecx, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 3969 of file chan_iax2.c.
References aes_decrypt_key128(), and aes_encrypt_key128().
Referenced by authenticate(), and decrypt_frame().
03970 { 03971 aes_encrypt_key128(digest, ecx); 03972 aes_decrypt_key128(digest, dcx); 03973 }
static struct iax2_peer * build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | temponly | |||
) | [static, read] |
Create peer structure based on configuration.
Definition at line 9110 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, ao2_alloc(), ao2_find(), ast_append_ha(), ast_callerid_split(), ast_clear_flag, ast_copy_flags, ast_dnsmgr_lookup(), ast_free_ha(), ast_get_ip(), ast_log(), ast_parse_allow_disallow(), ast_sched_del(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), iax2_peer::authmethods, iax2_peer::capability, cid_name, cid_num, iax2_peer::defaddr, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, iax2_peer::dnsmgr, iax2_peer::encmethods, iax2_peer::expire, iax2_peer::expiry, get_auth_methods(), get_encrypt_methods(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, ast_variable::lineno, LOG_NOTICE, LOG_WARNING, mailbox, iax2_peer::mask, iax2_peer::maxms, ast_variable::name, ast_variable::next, peer_destructor(), peer_set_srcaddr(), peer_unref(), peers, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, prefs, iax2_peer::prefs, iax2_registry::secret, iax2_peer::smoothing, iax2_peer::sockfd, unlink_peer(), and ast_variable::value.
09111 { 09112 struct iax2_peer *peer = NULL; 09113 struct ast_ha *oldha = NULL; 09114 int maskfound=0; 09115 int found=0; 09116 int firstpass=1; 09117 struct iax2_peer tmp_peer = { 09118 .name = name, 09119 }; 09120 09121 if (!temponly) { 09122 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 09123 if (peer && !ast_test_flag(peer, IAX_DELME)) 09124 firstpass = 0; 09125 } 09126 09127 if (peer) { 09128 found++; 09129 if (firstpass) { 09130 oldha = peer->ha; 09131 peer->ha = NULL; 09132 } 09133 unlink_peer(peer); 09134 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 09135 peer->expire = -1; 09136 peer->pokeexpire = -1; 09137 peer->sockfd = defaultsockfd; 09138 if (ast_string_field_init(peer, 32)) 09139 peer = peer_unref(peer); 09140 } 09141 09142 if (peer) { 09143 if (firstpass) { 09144 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09145 peer->encmethods = iax2_encryption; 09146 peer->adsi = adsi; 09147 ast_string_field_set(peer,secret,""); 09148 if (!found) { 09149 ast_string_field_set(peer, name, name); 09150 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09151 peer->expiry = min_reg_expire; 09152 } 09153 peer->prefs = prefs; 09154 peer->capability = iax2_capability; 09155 peer->smoothing = 0; 09156 peer->pokefreqok = DEFAULT_FREQ_OK; 09157 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 09158 ast_string_field_set(peer,context,""); 09159 ast_string_field_set(peer,peercontext,""); 09160 ast_clear_flag(peer, IAX_HASCALLERID); 09161 ast_string_field_set(peer, cid_name, ""); 09162 ast_string_field_set(peer, cid_num, ""); 09163 } 09164 09165 if (!v) { 09166 v = alt; 09167 alt = NULL; 09168 } 09169 while(v) { 09170 if (!strcasecmp(v->name, "secret")) { 09171 ast_string_field_set(peer, secret, v->value); 09172 } else if (!strcasecmp(v->name, "mailbox")) { 09173 ast_string_field_set(peer, mailbox, v->value); 09174 } else if (!strcasecmp(v->name, "mohinterpret")) { 09175 ast_string_field_set(peer, mohinterpret, v->value); 09176 } else if (!strcasecmp(v->name, "mohsuggest")) { 09177 ast_string_field_set(peer, mohsuggest, v->value); 09178 } else if (!strcasecmp(v->name, "dbsecret")) { 09179 ast_string_field_set(peer, dbsecret, v->value); 09180 } else if (!strcasecmp(v->name, "trunk")) { 09181 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 09182 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) { 09183 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name); 09184 ast_clear_flag(peer, IAX_TRUNK); 09185 } 09186 } else if (!strcasecmp(v->name, "auth")) { 09187 peer->authmethods = get_auth_methods(v->value); 09188 } else if (!strcasecmp(v->name, "encryption")) { 09189 peer->encmethods = get_encrypt_methods(v->value); 09190 } else if (!strcasecmp(v->name, "notransfer")) { 09191 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09192 ast_clear_flag(peer, IAX_TRANSFERMEDIA); 09193 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 09194 } else if (!strcasecmp(v->name, "transfer")) { 09195 if (!strcasecmp(v->value, "mediaonly")) { 09196 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09197 } else if (ast_true(v->value)) { 09198 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09199 } else 09200 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09201 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09202 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 09203 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09204 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 09205 } else if (!strcasecmp(v->name, "host")) { 09206 if (!strcasecmp(v->value, "dynamic")) { 09207 /* They'll register with us */ 09208 ast_set_flag(peer, IAX_DYNAMIC); 09209 if (!found) { 09210 /* Initialize stuff iff we're not found, otherwise 09211 we keep going with what we had */ 09212 memset(&peer->addr.sin_addr, 0, 4); 09213 if (peer->addr.sin_port) { 09214 /* If we've already got a port, make it the default rather than absolute */ 09215 peer->defaddr.sin_port = peer->addr.sin_port; 09216 peer->addr.sin_port = 0; 09217 } 09218 } 09219 } else { 09220 /* Non-dynamic. Make sure we become that way if we're not */ 09221 if (peer->expire > -1) 09222 ast_sched_del(sched, peer->expire); 09223 peer->expire = -1; 09224 ast_clear_flag(peer, IAX_DYNAMIC); 09225 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) 09226 return peer_unref(peer); 09227 if (!peer->addr.sin_port) 09228 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09229 } 09230 if (!maskfound) 09231 inet_aton("255.255.255.255", &peer->mask); 09232 } else if (!strcasecmp(v->name, "defaultip")) { 09233 if (ast_get_ip(&peer->defaddr, v->value)) 09234 return peer_unref(peer); 09235 } else if (!strcasecmp(v->name, "sourceaddress")) { 09236 peer_set_srcaddr(peer, v->value); 09237 } else if (!strcasecmp(v->name, "permit") || 09238 !strcasecmp(v->name, "deny")) { 09239 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 09240 } else if (!strcasecmp(v->name, "mask")) { 09241 maskfound++; 09242 inet_aton(v->value, &peer->mask); 09243 } else if (!strcasecmp(v->name, "context")) { 09244 ast_string_field_set(peer, context, v->value); 09245 } else if (!strcasecmp(v->name, "regexten")) { 09246 ast_string_field_set(peer, regexten, v->value); 09247 } else if (!strcasecmp(v->name, "peercontext")) { 09248 ast_string_field_set(peer, peercontext, v->value); 09249 } else if (!strcasecmp(v->name, "port")) { 09250 if (ast_test_flag(peer, IAX_DYNAMIC)) 09251 peer->defaddr.sin_port = htons(atoi(v->value)); 09252 else 09253 peer->addr.sin_port = htons(atoi(v->value)); 09254 } else if (!strcasecmp(v->name, "username")) { 09255 ast_string_field_set(peer, username, v->value); 09256 } else if (!strcasecmp(v->name, "allow")) { 09257 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 09258 } else if (!strcasecmp(v->name, "disallow")) { 09259 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 09260 } else if (!strcasecmp(v->name, "callerid")) { 09261 if (!ast_strlen_zero(v->value)) { 09262 char name2[80]; 09263 char num2[80]; 09264 ast_callerid_split(v->value, name2, 80, num2, 80); 09265 ast_string_field_set(peer, cid_name, name2); 09266 ast_string_field_set(peer, cid_num, num2); 09267 ast_set_flag(peer, IAX_HASCALLERID); 09268 } else { 09269 ast_clear_flag(peer, IAX_HASCALLERID); 09270 ast_string_field_set(peer, cid_name, ""); 09271 ast_string_field_set(peer, cid_num, ""); 09272 } 09273 } else if (!strcasecmp(v->name, "fullname")) { 09274 if (!ast_strlen_zero(v->value)) { 09275 ast_string_field_set(peer, cid_name, v->value); 09276 ast_set_flag(peer, IAX_HASCALLERID); 09277 } else { 09278 ast_string_field_set(peer, cid_name, ""); 09279 if (ast_strlen_zero(peer->cid_num)) 09280 ast_clear_flag(peer, IAX_HASCALLERID); 09281 } 09282 } else if (!strcasecmp(v->name, "cid_number")) { 09283 if (!ast_strlen_zero(v->value)) { 09284 ast_string_field_set(peer, cid_num, v->value); 09285 ast_set_flag(peer, IAX_HASCALLERID); 09286 } else { 09287 ast_string_field_set(peer, cid_num, ""); 09288 if (ast_strlen_zero(peer->cid_name)) 09289 ast_clear_flag(peer, IAX_HASCALLERID); 09290 } 09291 } else if (!strcasecmp(v->name, "sendani")) { 09292 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 09293 } else if (!strcasecmp(v->name, "inkeys")) { 09294 ast_string_field_set(peer, inkeys, v->value); 09295 } else if (!strcasecmp(v->name, "outkey")) { 09296 ast_string_field_set(peer, outkey, v->value); 09297 } else if (!strcasecmp(v->name, "qualify")) { 09298 if (!strcasecmp(v->value, "no")) { 09299 peer->maxms = 0; 09300 } else if (!strcasecmp(v->value, "yes")) { 09301 peer->maxms = DEFAULT_MAXMS; 09302 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 09303 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); 09304 peer->maxms = 0; 09305 } 09306 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 09307 peer->smoothing = ast_true(v->value); 09308 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 09309 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) { 09310 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); 09311 } 09312 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 09313 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) { 09314 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); 09315 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 09316 } else if (!strcasecmp(v->name, "timezone")) { 09317 ast_string_field_set(peer, zonetag, v->value); 09318 } else if (!strcasecmp(v->name, "adsi")) { 09319 peer->adsi = ast_true(v->value); 09320 }/* else if (strcasecmp(v->name,"type")) */ 09321 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09322 v = v->next; 09323 if (!v) { 09324 v = alt; 09325 alt = NULL; 09326 } 09327 } 09328 if (!peer->authmethods) 09329 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09330 ast_clear_flag(peer, IAX_DELME); 09331 /* Make sure these are IPv4 addresses */ 09332 peer->addr.sin_family = AF_INET; 09333 } 09334 if (oldha) 09335 ast_free_ha(oldha); 09336 return peer; 09337 }
static struct iax2_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | temponly | |||
) | [static, read] |
Create in-memory user structure from configuration.
Definition at line 9353 of file chan_iax2.c.
References iax2_user::adsi, iax2_user::amaflags, ao2_alloc(), ao2_find(), ao2_unlink(), ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_free_ha(), ast_log(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_strdupa, ast_string_field_build, ast_string_field_free_memory, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), iax2_user::authmethods, build_context(), iax2_user::capability, cid_name, cid_num, cleanup(), iax2_user::contexts, iax2_user::curauthreq, iax2_user::encmethods, format, free_context(), get_auth_methods(), get_encrypt_methods(), iax2_user::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DELME, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, ast_variable::lineno, LOG_NOTICE, LOG_WARNING, iax2_user::maxauthreq, ast_variable::name, ast_variable::next, iax2_context::next, prefs, iax2_user::prefs, iax2_registry::secret, user_destructor(), user_unref(), users, ast_variable::value, and iax2_user::vars.
09354 { 09355 struct iax2_user *user = NULL; 09356 struct iax2_context *con, *conl = NULL; 09357 struct ast_ha *oldha = NULL; 09358 struct iax2_context *oldcon = NULL; 09359 int format; 09360 int firstpass=1; 09361 int oldcurauthreq = 0; 09362 char *varname = NULL, *varval = NULL; 09363 struct ast_variable *tmpvar = NULL; 09364 struct iax2_user tmp_user = { 09365 .name = name, 09366 }; 09367 09368 if (!temponly) { 09369 user = ao2_find(users, &tmp_user, OBJ_POINTER); 09370 if (user && !ast_test_flag(user, IAX_DELME)) 09371 firstpass = 0; 09372 } 09373 09374 if (user) { 09375 if (firstpass) { 09376 oldcurauthreq = user->curauthreq; 09377 oldha = user->ha; 09378 oldcon = user->contexts; 09379 user->ha = NULL; 09380 user->contexts = NULL; 09381 } 09382 /* Already in the list, remove it and it will be added back (or FREE'd) */ 09383 ao2_unlink(users, user); 09384 } else { 09385 user = ao2_alloc(sizeof(*user), user_destructor); 09386 } 09387 09388 if (user) { 09389 if (firstpass) { 09390 ast_string_field_free_memory(user); 09391 memset(user, 0, sizeof(struct iax2_user)); 09392 if (ast_string_field_init(user, 32)) { 09393 user = user_unref(user); 09394 goto cleanup; 09395 } 09396 user->maxauthreq = maxauthreq; 09397 user->curauthreq = oldcurauthreq; 09398 user->prefs = prefs; 09399 user->capability = iax2_capability; 09400 user->encmethods = iax2_encryption; 09401 user->adsi = adsi; 09402 ast_string_field_set(user, name, name); 09403 ast_string_field_set(user, language, language); 09404 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 09405 ast_clear_flag(user, IAX_HASCALLERID); 09406 ast_string_field_set(user, cid_name, ""); 09407 ast_string_field_set(user, cid_num, ""); 09408 } 09409 if (!v) { 09410 v = alt; 09411 alt = NULL; 09412 } 09413 while(v) { 09414 if (!strcasecmp(v->name, "context")) { 09415 con = build_context(v->value); 09416 if (con) { 09417 if (conl) 09418 conl->next = con; 09419 else 09420 user->contexts = con; 09421 conl = con; 09422 } 09423 } else if (!strcasecmp(v->name, "permit") || 09424 !strcasecmp(v->name, "deny")) { 09425 user->ha = ast_append_ha(v->name, v->value, user->ha); 09426 } else if (!strcasecmp(v->name, "setvar")) { 09427 varname = ast_strdupa(v->value); 09428 if (varname && (varval = strchr(varname,'='))) { 09429 *varval = '\0'; 09430 varval++; 09431 if((tmpvar = ast_variable_new(varname, varval))) { 09432 tmpvar->next = user->vars; 09433 user->vars = tmpvar; 09434 } 09435 } 09436 } else if (!strcasecmp(v->name, "allow")) { 09437 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 09438 } else if (!strcasecmp(v->name, "disallow")) { 09439 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 09440 } else if (!strcasecmp(v->name, "trunk")) { 09441 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 09442 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) { 09443 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name); 09444 ast_clear_flag(user, IAX_TRUNK); 09445 } 09446 } else if (!strcasecmp(v->name, "auth")) { 09447 user->authmethods = get_auth_methods(v->value); 09448 } else if (!strcasecmp(v->name, "encryption")) { 09449 user->encmethods = get_encrypt_methods(v->value); 09450 } else if (!strcasecmp(v->name, "notransfer")) { 09451 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09452 ast_clear_flag(user, IAX_TRANSFERMEDIA); 09453 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 09454 } else if (!strcasecmp(v->name, "transfer")) { 09455 if (!strcasecmp(v->value, "mediaonly")) { 09456 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09457 } else if (ast_true(v->value)) { 09458 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09459 } else 09460 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09461 } else if (!strcasecmp(v->name, "codecpriority")) { 09462 if(!strcasecmp(v->value, "caller")) 09463 ast_set_flag(user, IAX_CODEC_USER_FIRST); 09464 else if(!strcasecmp(v->value, "disabled")) 09465 ast_set_flag(user, IAX_CODEC_NOPREFS); 09466 else if(!strcasecmp(v->value, "reqonly")) { 09467 ast_set_flag(user, IAX_CODEC_NOCAP); 09468 ast_set_flag(user, IAX_CODEC_NOPREFS); 09469 } 09470 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09471 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 09472 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09473 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 09474 } else if (!strcasecmp(v->name, "dbsecret")) { 09475 ast_string_field_set(user, dbsecret, v->value); 09476 } else if (!strcasecmp(v->name, "secret")) { 09477 if (!ast_strlen_zero(user->secret)) { 09478 char *old = ast_strdupa(user->secret); 09479 09480 ast_string_field_build(user, secret, "%s;%s", old, v->value); 09481 } else 09482 ast_string_field_set(user, secret, v->value); 09483 } else if (!strcasecmp(v->name, "callerid")) { 09484 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 09485 char name2[80]; 09486 char num2[80]; 09487 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 09488 ast_string_field_set(user, cid_name, name2); 09489 ast_string_field_set(user, cid_num, num2); 09490 ast_set_flag(user, IAX_HASCALLERID); 09491 } else { 09492 ast_clear_flag(user, IAX_HASCALLERID); 09493 ast_string_field_set(user, cid_name, ""); 09494 ast_string_field_set(user, cid_num, ""); 09495 } 09496 } else if (!strcasecmp(v->name, "fullname")) { 09497 if (!ast_strlen_zero(v->value)) { 09498 ast_string_field_set(user, cid_name, v->value); 09499 ast_set_flag(user, IAX_HASCALLERID); 09500 } else { 09501 ast_string_field_set(user, cid_name, ""); 09502 if (ast_strlen_zero(user->cid_num)) 09503 ast_clear_flag(user, IAX_HASCALLERID); 09504 } 09505 } else if (!strcasecmp(v->name, "cid_number")) { 09506 if (!ast_strlen_zero(v->value)) { 09507 ast_string_field_set(user, cid_num, v->value); 09508 ast_set_flag(user, IAX_HASCALLERID); 09509 } else { 09510 ast_string_field_set(user, cid_num, ""); 09511 if (ast_strlen_zero(user->cid_name)) 09512 ast_clear_flag(user, IAX_HASCALLERID); 09513 } 09514 } else if (!strcasecmp(v->name, "accountcode")) { 09515 ast_string_field_set(user, accountcode, v->value); 09516 } else if (!strcasecmp(v->name, "mohinterpret")) { 09517 ast_string_field_set(user, mohinterpret, v->value); 09518 } else if (!strcasecmp(v->name, "mohsuggest")) { 09519 ast_string_field_set(user, mohsuggest, v->value); 09520 } else if (!strcasecmp(v->name, "language")) { 09521 ast_string_field_set(user, language, v->value); 09522 } else if (!strcasecmp(v->name, "amaflags")) { 09523 format = ast_cdr_amaflags2int(v->value); 09524 if (format < 0) { 09525 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 09526 } else { 09527 user->amaflags = format; 09528 } 09529 } else if (!strcasecmp(v->name, "inkeys")) { 09530 ast_string_field_set(user, inkeys, v->value); 09531 } else if (!strcasecmp(v->name, "maxauthreq")) { 09532 user->maxauthreq = atoi(v->value); 09533 if (user->maxauthreq < 0) 09534 user->maxauthreq = 0; 09535 } else if (!strcasecmp(v->name, "adsi")) { 09536 user->adsi = ast_true(v->value); 09537 }/* else if (strcasecmp(v->name,"type")) */ 09538 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09539 v = v->next; 09540 if (!v) { 09541 v = alt; 09542 alt = NULL; 09543 } 09544 } 09545 if (!user->authmethods) { 09546 if (!ast_strlen_zero(user->secret)) { 09547 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09548 if (!ast_strlen_zero(user->inkeys)) 09549 user->authmethods |= IAX_AUTH_RSA; 09550 } else if (!ast_strlen_zero(user->inkeys)) { 09551 user->authmethods = IAX_AUTH_RSA; 09552 } else { 09553 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09554 } 09555 } 09556 ast_clear_flag(user, IAX_DELME); 09557 } 09558 cleanup: 09559 if (oldha) 09560 ast_free_ha(oldha); 09561 if (oldcon) 09562 free_context(oldcon); 09563 return user; 09564 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 10070 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_strdupa, ast_string_field_set, iax_ie_data::buf, iax2_registry::callno, chan_iax2_pvt::capability, parsed_dial_string::context, create_addr(), parsed_dial_string::exten, find_callno(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_COMMAND_NEW, iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CAPABILITY, IAX_IE_FORMAT, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_MAX_CALLS, IAX_PROTO_VERSION, iaxs, iaxsl, parsed_dial_string::key, LOG_DEBUG, LOG_WARNING, NEW_FORCE, option_debug, parse_dial_string(), parsed_dial_string::password, parsed_dial_string::peer, iax_ie_data::pos, iax2_registry::secret, send_command(), create_addr_info::sockfd, and parsed_dial_string::username.
Referenced by find_cache().
10071 { 10072 struct sockaddr_in sin; 10073 int x; 10074 int callno; 10075 struct iax_ie_data ied; 10076 struct create_addr_info cai; 10077 struct parsed_dial_string pds; 10078 char *tmpstr; 10079 10080 for (x=0; x<IAX_MAX_CALLS; x++) { 10081 /* Look for an *exact match* call. Once a call is negotiated, it can only 10082 look up entries for a single context */ 10083 if (!ast_mutex_trylock(&iaxsl[x])) { 10084 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 10085 return x; 10086 ast_mutex_unlock(&iaxsl[x]); 10087 } 10088 } 10089 10090 /* No match found, we need to create a new one */ 10091 10092 memset(&cai, 0, sizeof(cai)); 10093 memset(&ied, 0, sizeof(ied)); 10094 memset(&pds, 0, sizeof(pds)); 10095 10096 tmpstr = ast_strdupa(data); 10097 parse_dial_string(tmpstr, &pds); 10098 10099 /* Populate our address from the given */ 10100 if (create_addr(pds.peer, &sin, &cai)) 10101 return -1; 10102 10103 if (option_debug) 10104 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n", 10105 pds.peer, pds.username, pds.password, pds.context); 10106 10107 callno = find_callno(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 10108 if (callno < 1) { 10109 ast_log(LOG_WARNING, "Unable to create call\n"); 10110 return -1; 10111 } 10112 10113 ast_mutex_lock(&iaxsl[callno]); 10114 ast_string_field_set(iaxs[callno], dproot, data); 10115 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 10116 10117 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 10118 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 10119 /* the string format is slightly different from a standard dial string, 10120 because the context appears in the 'exten' position 10121 */ 10122 if (pds.exten) 10123 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 10124 if (pds.username) 10125 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 10126 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 10127 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 10128 /* Keep password handy */ 10129 if (pds.password) 10130 ast_string_field_set(iaxs[callno], secret, pds.password); 10131 if (pds.key) 10132 ast_string_field_set(iaxs[callno], outkey, pds.key); 10133 /* Start the call going */ 10134 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 10135 10136 return callno; 10137 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 3837 of file chan_iax2.c.
References ast_log(), ast_random(), ast_tvsub(), chan_iax2_pvt::callno, LOG_DEBUG, option_debug, and chan_iax2_pvt::rxcore.
03838 { 03839 /* Returns where in "receive time" we are. That is, how many ms 03840 since we received (or would have received) the frame with timestamp 0 */ 03841 int ms; 03842 #ifdef IAXTESTS 03843 int jit; 03844 #endif /* IAXTESTS */ 03845 /* Setup rxcore if necessary */ 03846 if (ast_tvzero(p->rxcore)) { 03847 p->rxcore = ast_tvnow(); 03848 if (option_debug && iaxdebug) 03849 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 03850 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 03851 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 03852 #if 1 03853 if (option_debug && iaxdebug) 03854 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 03855 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 03856 #endif 03857 } 03858 03859 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 03860 #ifdef IAXTESTS 03861 if (test_jit) { 03862 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 03863 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 03864 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 03865 jit = -jit; 03866 ms += jit; 03867 } 03868 } 03869 if (test_late) { 03870 ms += test_late; 03871 test_late = 0; 03872 } 03873 #endif /* IAXTESTS */ 03874 return ms; 03875 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 3719 of file chan_iax2.c.
References AST_FRAME_CNG, AST_FRAME_IAX, AST_FRAME_VOICE, ast_log(), ast_tvadd(), ast_tvsub(), chan_iax2_pvt::callno, ast_frame::delivery, ast_frame::frametype, iaxs, chan_iax2_pvt::lastsent, LOG_DEBUG, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, chan_iax2_pvt::offset, option_debug, chan_iax2_pvt::peercallno, and ast_frame::samples.
Referenced by iax2_send(), and socket_process().
03720 { 03721 int ms; 03722 int voice = 0; 03723 int genuine = 0; 03724 int adjust; 03725 struct timeval *delivery = NULL; 03726 03727 03728 /* What sort of frame do we have?: voice is self-explanatory 03729 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 03730 non-genuine frames are CONTROL frames [ringing etc], DTMF 03731 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 03732 the others need a timestamp slaved to the voice frames so that they go in sequence 03733 */ 03734 if (f) { 03735 if (f->frametype == AST_FRAME_VOICE) { 03736 voice = 1; 03737 delivery = &f->delivery; 03738 } else if (f->frametype == AST_FRAME_IAX) { 03739 genuine = 1; 03740 } else if (f->frametype == AST_FRAME_CNG) { 03741 p->notsilenttx = 0; 03742 } 03743 } 03744 if (ast_tvzero(p->offset)) { 03745 gettimeofday(&p->offset, NULL); 03746 /* Round to nearest 20ms for nice looking traces */ 03747 p->offset.tv_usec -= p->offset.tv_usec % 20000; 03748 } 03749 /* If the timestamp is specified, just send it as is */ 03750 if (ts) 03751 return ts; 03752 /* If we have a time that the frame arrived, always use it to make our timestamp */ 03753 if (delivery && !ast_tvzero(*delivery)) { 03754 ms = ast_tvdiff_ms(*delivery, p->offset); 03755 if (option_debug > 2 && iaxdebug) 03756 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 03757 } else { 03758 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 03759 if (ms < 0) 03760 ms = 0; 03761 if (voice) { 03762 /* On a voice frame, use predicted values if appropriate */ 03763 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 03764 /* Adjust our txcore, keeping voice and non-voice synchronized */ 03765 /* AN EXPLANATION: 03766 When we send voice, we usually send "calculated" timestamps worked out 03767 on the basis of the number of samples sent. When we send other frames, 03768 we usually send timestamps worked out from the real clock. 03769 The problem is that they can tend to drift out of step because the 03770 source channel's clock and our clock may not be exactly at the same rate. 03771 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 03772 for this call. Moving it adjusts timestamps for non-voice frames. 03773 We make the adjustment in the style of a moving average. Each time we 03774 adjust p->offset by 10% of the difference between our clock-derived 03775 timestamp and the predicted timestamp. That's why you see "10000" 03776 below even though IAX2 timestamps are in milliseconds. 03777 The use of a moving average avoids offset moving too radically. 03778 Generally, "adjust" roams back and forth around 0, with offset hardly 03779 changing at all. But if a consistent different starts to develop it 03780 will be eliminated over the course of 10 frames (200-300msecs) 03781 */ 03782 adjust = (ms - p->nextpred); 03783 if (adjust < 0) 03784 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 03785 else if (adjust > 0) 03786 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 03787 03788 if (!p->nextpred) { 03789 p->nextpred = ms; /*f->samples / 8;*/ 03790 if (p->nextpred <= p->lastsent) 03791 p->nextpred = p->lastsent + 3; 03792 } 03793 ms = p->nextpred; 03794 } else { 03795 /* in this case, just use the actual 03796 * time, since we're either way off 03797 * (shouldn't happen), or we're ending a 03798 * silent period -- and seed the next 03799 * predicted time. Also, round ms to the 03800 * next multiple of frame size (so our 03801 * silent periods are multiples of 03802 * frame size too) */ 03803 03804 if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 03805 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 03806 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 03807 03808 if (f->samples >= 8) /* check to make sure we dont core dump */ 03809 { 03810 int diff = ms % (f->samples / 8); 03811 if (diff) 03812 ms += f->samples/8 - diff; 03813 } 03814 03815 p->nextpred = ms; 03816 p->notsilenttx = 1; 03817 } 03818 } else { 03819 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 03820 it's a genuine frame */ 03821 if (genuine) { 03822 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 03823 if (ms <= p->lastsent) 03824 ms = p->lastsent + 3; 03825 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 03826 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 03827 ms = p->lastsent + 3; 03828 } 03829 } 03830 } 03831 p->lastsent = ms; 03832 if (voice) 03833 p->nextpred = p->nextpred + f->samples / 8; 03834 return ms; 03835 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | tv | |||
) | [static] |
Definition at line 3675 of file chan_iax2.c.
References iax2_trunk_peer::lastsent, iax2_trunk_peer::lasttxtime, MAX_TIMESTAMP_SKEW, iax2_trunk_peer::trunkact, and iax2_trunk_peer::txtrunktime.
Referenced by send_trunk().
03676 { 03677 unsigned long int mssincetx; /* unsigned to handle overflows */ 03678 long int ms, pred; 03679 03680 tpeer->trunkact = *tv; 03681 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime); 03682 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 03683 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 03684 tpeer->txtrunktime = *tv; 03685 tpeer->lastsent = 999999; 03686 } 03687 /* Update last transmit time now */ 03688 tpeer->lasttxtime = *tv; 03689 03690 /* Calculate ms offset */ 03691 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime); 03692 /* Predict from last value */ 03693 pred = tpeer->lastsent + sampms; 03694 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 03695 ms = pred; 03696 03697 /* We never send the same timestamp twice, so fudge a little if we must */ 03698 if (ms == tpeer->lastsent) 03699 ms = tpeer->lastsent + 1; 03700 tpeer->lastsent = ms; 03701 return ms; 03702 }
static int check_access | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Definition at line 4937 of file chan_iax2.c.
References iax2_user::adsi, chan_iax2_pvt::adsi, iax_ies::adsicpe, chan_iax2_pvt::amaflags, iax2_user::amaflags, ao2_iterator_init(), ao2_iterator_next(), apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, ast_set2_flag, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_variable_new(), iax2_user::authmethods, chan_iax2_pvt::authmethods, iax_ies::called_context, iax_ies::called_number, iax_ies::calling_ani, iax_ies::calling_name, iax_ies::calling_number, chan_iax2_pvt::calling_pres, iax_ies::calling_pres, chan_iax2_pvt::calling_tns, iax_ies::calling_tns, chan_iax2_pvt::calling_ton, iax_ies::calling_ton, iax2_user::capability, chan_iax2_pvt::capability, iax_ies::capability, cid_name, cid_num, iax_ies::codec_prefs, iax2_context::context, iax2_user::contexts, iax_ies::dnid, iax2_user::encmethods, chan_iax2_pvt::encmethods, exten, iax_ies::format, iax2_user::ha, iax2_getpeertrunk(), IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_MAXAUTHREQ, IAX_NOTRANSFER, IAX_PROTO_VERSION, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, key(), iax_ies::language, LOG_WARNING, iax2_user::maxauthreq, ast_variable::name, ast_variable::next, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_user::prefs, chan_iax2_pvt::prefs, prefs, iax_ies::rdnis, realtime_user(), iax2_registry::secret, user_unref(), iax_ies::username, users, ast_variable::value, chan_iax2_pvt::vars, iax2_user::vars, and iax_ies::version.
Referenced by socket_process().
04938 { 04939 /* Start pessimistic */ 04940 int res = -1; 04941 int version = 2; 04942 struct iax2_user *user = NULL, *best = NULL; 04943 int bestscore = 0; 04944 int gotcapability = 0; 04945 struct ast_variable *v = NULL, *tmpvar = NULL; 04946 struct ao2_iterator i; 04947 04948 if (!iaxs[callno]) 04949 return res; 04950 if (ies->called_number) 04951 ast_string_field_set(iaxs[callno], exten, ies->called_number); 04952 if (ies->calling_number) { 04953 ast_shrink_phone_number(ies->calling_number); 04954 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 04955 } 04956 if (ies->calling_name) 04957 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 04958 if (ies->calling_ani) 04959 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 04960 if (ies->dnid) 04961 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 04962 if (ies->rdnis) 04963 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 04964 if (ies->called_context) 04965 ast_string_field_set(iaxs[callno], context, ies->called_context); 04966 if (ies->language) 04967 ast_string_field_set(iaxs[callno], language, ies->language); 04968 if (ies->username) 04969 ast_string_field_set(iaxs[callno], username, ies->username); 04970 if (ies->calling_ton > -1) 04971 iaxs[callno]->calling_ton = ies->calling_ton; 04972 if (ies->calling_tns > -1) 04973 iaxs[callno]->calling_tns = ies->calling_tns; 04974 if (ies->calling_pres > -1) 04975 iaxs[callno]->calling_pres = ies->calling_pres; 04976 if (ies->format) 04977 iaxs[callno]->peerformat = ies->format; 04978 if (ies->adsicpe) 04979 iaxs[callno]->peeradsicpe = ies->adsicpe; 04980 if (ies->capability) { 04981 gotcapability = 1; 04982 iaxs[callno]->peercapability = ies->capability; 04983 } 04984 if (ies->version) 04985 version = ies->version; 04986 04987 /* Use provided preferences until told otherwise for actual preferences */ 04988 if(ies->codec_prefs) { 04989 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 04990 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 04991 } 04992 04993 if (!gotcapability) 04994 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 04995 if (version > IAX_PROTO_VERSION) { 04996 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 04997 ast_inet_ntoa(sin->sin_addr), version); 04998 return res; 04999 } 05000 /* Search the userlist for a compatible entry, and fill in the rest */ 05001 i = ao2_iterator_init(users, 0); 05002 while ((user = ao2_iterator_next(&i))) { 05003 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 05004 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 05005 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 05006 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 05007 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 05008 if (!ast_strlen_zero(iaxs[callno]->username)) { 05009 /* Exact match, stop right now. */ 05010 if (best) 05011 user_unref(best); 05012 best = user; 05013 break; 05014 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->inkeys)) { 05015 /* No required authentication */ 05016 if (user->ha) { 05017 /* There was host authentication and we passed, bonus! */ 05018 if (bestscore < 4) { 05019 bestscore = 4; 05020 if (best) 05021 user_unref(best); 05022 best = user; 05023 continue; 05024 } 05025 } else { 05026 /* No host access, but no secret, either, not bad */ 05027 if (bestscore < 3) { 05028 bestscore = 3; 05029 if (best) 05030 user_unref(best); 05031 best = user; 05032 continue; 05033 } 05034 } 05035 } else { 05036 if (user->ha) { 05037 /* Authentication, but host access too, eh, it's something.. */ 05038 if (bestscore < 2) { 05039 bestscore = 2; 05040 if (best) 05041 user_unref(best); 05042 best = user; 05043 continue; 05044 } 05045 } else { 05046 /* Authentication and no host access... This is our baseline */ 05047 if (bestscore < 1) { 05048 bestscore = 1; 05049 if (best) 05050 user_unref(best); 05051 best = user; 05052 continue; 05053 } 05054 } 05055 } 05056 } 05057 user_unref(user); 05058 } 05059 user = best; 05060 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 05061 user = realtime_user(iaxs[callno]->username, sin); 05062 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 05063 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 05064 user = user_unref(user); 05065 } 05066 } 05067 if (user) { 05068 /* We found our match (use the first) */ 05069 /* copy vars */ 05070 for (v = user->vars ; v ; v = v->next) { 05071 if((tmpvar = ast_variable_new(v->name, v->value))) { 05072 tmpvar->next = iaxs[callno]->vars; 05073 iaxs[callno]->vars = tmpvar; 05074 } 05075 } 05076 /* If a max AUTHREQ restriction is in place, activate it */ 05077 if (user->maxauthreq > 0) 05078 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ); 05079 iaxs[callno]->prefs = user->prefs; 05080 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST); 05081 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS); 05082 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP); 05083 iaxs[callno]->encmethods = user->encmethods; 05084 /* Store the requested username if not specified */ 05085 if (ast_strlen_zero(iaxs[callno]->username)) 05086 ast_string_field_set(iaxs[callno], username, user->name); 05087 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 05088 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 05089 iaxs[callno]->capability = user->capability; 05090 /* And use the default context */ 05091 if (ast_strlen_zero(iaxs[callno]->context)) { 05092 if (user->contexts) 05093 ast_string_field_set(iaxs[callno], context, user->contexts->context); 05094 else 05095 ast_string_field_set(iaxs[callno], context, context); 05096 } 05097 /* And any input keys */ 05098 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 05099 /* And the permitted authentication methods */ 05100 iaxs[callno]->authmethods = user->authmethods; 05101 iaxs[callno]->adsi = user->adsi; 05102 /* If they have callerid, override the given caller id. Always store the ANI */ 05103 if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) { 05104 if (ast_test_flag(user, IAX_HASCALLERID)) { 05105 iaxs[callno]->calling_tns = 0; 05106 iaxs[callno]->calling_ton = 0; 05107 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 05108 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 05109 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 05110 } 05111 if (ast_strlen_zero(iaxs[callno]->ani)) 05112 ast_string_field_set(iaxs[callno], ani, user->cid_num); 05113 } else { 05114 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 05115 } 05116 if (!ast_strlen_zero(user->accountcode)) 05117 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 05118 if (!ast_strlen_zero(user->mohinterpret)) 05119 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 05120 if (!ast_strlen_zero(user->mohsuggest)) 05121 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 05122 if (user->amaflags) 05123 iaxs[callno]->amaflags = user->amaflags; 05124 if (!ast_strlen_zero(user->language)) 05125 ast_string_field_set(iaxs[callno], language, user->language); 05126 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 05127 /* Keep this check last */ 05128 if (!ast_strlen_zero(user->dbsecret)) { 05129 char *family, *key=NULL; 05130 char buf[80]; 05131 family = ast_strdupa(user->dbsecret); 05132 key = strchr(family, '/'); 05133 if (key) { 05134 *key = '\0'; 05135 key++; 05136 } 05137 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 05138 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 05139 else 05140 ast_string_field_set(iaxs[callno], secret, buf); 05141 } else 05142 ast_string_field_set(iaxs[callno], secret, user->secret); 05143 res = 0; 05144 user = user_unref(user); 05145 } 05146 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 05147 return res; 05148 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 6627 of file chan_iax2.c.
References ast_log(), iax2_provision(), iax_provision_version(), LOG_DEBUG, and option_debug.
Referenced by socket_process().
06628 { 06629 unsigned int ourver; 06630 char rsi[80]; 06631 snprintf(rsi, sizeof(rsi), "si-%s", si); 06632 if (iax_provision_version(&ourver, rsi, 1)) 06633 return 0; 06634 if (option_debug) 06635 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 06636 if (ourver != ver) 06637 iax2_provision(sin, sockfd, NULL, rsi, 1); 06638 return 0; 06639 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 8990 of file chan_iax2.c.
References ast_log(), errno, LOG_DEBUG, LOG_ERROR, and option_debug.
Referenced by peer_set_srcaddr().
08991 { 08992 int sd; 08993 int res; 08994 08995 sd = socket(AF_INET, SOCK_DGRAM, 0); 08996 if (sd < 0) { 08997 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 08998 return -1; 08999 } 09000 09001 res = bind(sd, sa, salen); 09002 if (res < 0) { 09003 if (option_debug) 09004 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno)); 09005 close(sd); 09006 return 1; 09007 } 09008 09009 close(sd); 09010 return 0; 09011 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5633 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_UNKNOWN, iax_ies::called_number, iax2_dpcache::callno, chan_iax2_pvt::dpentries, iax_ies::dpstatus, iax2_dpcache::expiry, expiry, iax2_dpcache::exten, exten, iax2_dpcache::flags, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, iax2_dpcache::orig, iax2_dpcache::peer, iax_ies::refresh, and iax2_dpcache::waiters.
Referenced by socket_process().
05634 { 05635 char exten[256] = ""; 05636 int status = CACHE_FLAG_UNKNOWN; 05637 int expiry = iaxdefaultdpcache; 05638 int x; 05639 int matchmore = 0; 05640 struct iax2_dpcache *dp, *prev; 05641 05642 if (ies->called_number) 05643 ast_copy_string(exten, ies->called_number, sizeof(exten)); 05644 05645 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 05646 status = CACHE_FLAG_EXISTS; 05647 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 05648 status = CACHE_FLAG_CANEXIST; 05649 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 05650 status = CACHE_FLAG_NONEXISTENT; 05651 05652 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) { 05653 /* Don't really do anything with this */ 05654 } 05655 if (ies->refresh) 05656 expiry = ies->refresh; 05657 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 05658 matchmore = CACHE_FLAG_MATCHMORE; 05659 ast_mutex_lock(&dpcache_lock); 05660 prev = NULL; 05661 dp = pvt->dpentries; 05662 while(dp) { 05663 if (!strcmp(dp->exten, exten)) { 05664 /* Let them go */ 05665 if (prev) 05666 prev->peer = dp->peer; 05667 else 05668 pvt->dpentries = dp->peer; 05669 dp->peer = NULL; 05670 dp->callno = 0; 05671 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 05672 if (dp->flags & CACHE_FLAG_PENDING) { 05673 dp->flags &= ~CACHE_FLAG_PENDING; 05674 dp->flags |= status; 05675 dp->flags |= matchmore; 05676 } 05677 /* Wake up waiters */ 05678 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 05679 if (dp->waiters[x] > -1) 05680 write(dp->waiters[x], "asdf", 4); 05681 } 05682 prev = dp; 05683 dp = dp->peer; 05684 } 05685 ast_mutex_unlock(&dpcache_lock); 05686 return 0; 05687 }
static char* complete_iax2_show_peer | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2303 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_strdup, peer_unref(), and peers.
02304 { 02305 int which = 0; 02306 struct iax2_peer *peer; 02307 char *res = NULL; 02308 int wordlen = strlen(word); 02309 struct ao2_iterator i; 02310 02311 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */ 02312 if (pos != 3) 02313 return NULL; 02314 02315 i = ao2_iterator_init(peers, 0); 02316 while ((peer = ao2_iterator_next(&i))) { 02317 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) { 02318 res = ast_strdup(peer->name); 02319 peer_unref(peer); 02320 break; 02321 } 02322 peer_unref(peer); 02323 } 02324 02325 return res; 02326 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5689 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), iax_frame::callno, iax_ies::callno, jb_frame::data, DEFAULT_RETRY_TIME, iax2_frame_free(), iaxq, iaxs, chan_iax2_pvt::iseqno, chan_iax2_pvt::jb, jb_getall(), JB_OK, jb_reset(), chan_iax2_pvt::lag, chan_iax2_pvt::last, chan_iax2_pvt::lastsent, LOG_WARNING, chan_iax2_pvt::nextpred, chan_iax2_pvt::offset, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, iax_frame::retries, chan_iax2_pvt::rseqno, chan_iax2_pvt::rxcore, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, TRANSFER_NONE, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, chan_iax2_pvt::videoformat, and chan_iax2_pvt::voiceformat.
Referenced by socket_process().
05690 { 05691 int peercallno = 0; 05692 struct chan_iax2_pvt *pvt = iaxs[callno]; 05693 struct iax_frame *cur; 05694 jb_frame frame; 05695 05696 if (ies->callno) 05697 peercallno = ies->callno; 05698 05699 if (peercallno < 1) { 05700 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05701 return -1; 05702 } 05703 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 05704 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 05705 /* Reset sequence numbers */ 05706 pvt->oseqno = 0; 05707 pvt->rseqno = 0; 05708 pvt->iseqno = 0; 05709 pvt->aseqno = 0; 05710 pvt->peercallno = peercallno; 05711 pvt->transferring = TRANSFER_NONE; 05712 pvt->svoiceformat = -1; 05713 pvt->voiceformat = 0; 05714 pvt->svideoformat = -1; 05715 pvt->videoformat = 0; 05716 pvt->transfercallno = -1; 05717 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 05718 memset(&pvt->offset, 0, sizeof(pvt->offset)); 05719 /* reset jitterbuffer */ 05720 while(jb_getall(pvt->jb,&frame) == JB_OK) 05721 iax2_frame_free(frame.data); 05722 jb_reset(pvt->jb); 05723 pvt->lag = 0; 05724 pvt->last = 0; 05725 pvt->lastsent = 0; 05726 pvt->nextpred = 0; 05727 pvt->pingtime = DEFAULT_RETRY_TIME; 05728 AST_LIST_LOCK(&iaxq.queue); 05729 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 05730 /* We must cancel any packets that would have been transmitted 05731 because now we're talking to someone new. It's okay, they 05732 were transmitted to someone that didn't care anyway. */ 05733 if (callno == cur->callno) 05734 cur->retries = -1; 05735 } 05736 AST_LIST_UNLOCK(&iaxq.queue); 05737 return 0; 05738 }
static unsigned char compress_subclass | ( | int | subclass | ) | [static] |
Definition at line 1039 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().
01040 { 01041 int x; 01042 int power=-1; 01043 /* If it's 128 or smaller, just return it */ 01044 if (subclass < IAX_FLAG_SC_LOG) 01045 return subclass; 01046 /* Otherwise find its power */ 01047 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01048 if (subclass & (1 << x)) { 01049 if (power > -1) { 01050 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 01051 return 0; 01052 } else 01053 power = x; 01054 } 01055 } 01056 return power | IAX_FLAG_SC_LOG; 01057 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 6641 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().
06642 { 06643 jb_info stats; 06644 jb_getinfo(pvt->jb, &stats); 06645 06646 memset(iep, 0, sizeof(*iep)); 06647 06648 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 06649 if(stats.frames_in == 0) stats.frames_in = 1; 06650 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 06651 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 06652 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 06653 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 06654 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 06655 }
static int create_addr | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 2920 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, create_addr_info::adsi, ast_clear_flag, ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_gethostbyname(), ast_log(), ast_strdupa, ast_strlen_zero(), iax2_peer::capability, create_addr_info::capability, create_addr_info::context, iax2_peer::defaddr, iax2_peer::encmethods, create_addr_info::encmethods, find_peer(), create_addr_info::found, hp, IAX_DEFAULT_PORTNO, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, key(), iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, create_addr_info::maxtime, create_addr_info::mohinterpret, create_addr_info::mohsuggest, create_addr_info::outkey, peer_unref(), create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, prefs, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, create_addr_info::timezone, and create_addr_info::username.
02921 { 02922 struct ast_hostent ahp; 02923 struct hostent *hp; 02924 struct iax2_peer *peer; 02925 int res = -1; 02926 02927 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 02928 cai->sockfd = defaultsockfd; 02929 cai->maxtime = 0; 02930 sin->sin_family = AF_INET; 02931 02932 if (!(peer = find_peer(peername, 1))) { 02933 cai->found = 0; 02934 02935 hp = ast_gethostbyname(peername, &ahp); 02936 if (hp) { 02937 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 02938 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 02939 /* use global iax prefs for unknown peer/user */ 02940 ast_codec_pref_convert(&prefs, cai->prefs, sizeof(cai->prefs), 1); 02941 return 0; 02942 } else { 02943 ast_log(LOG_WARNING, "No such host: %s\n", peername); 02944 return -1; 02945 } 02946 } 02947 02948 cai->found = 1; 02949 02950 /* if the peer has no address (current or default), return failure */ 02951 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) 02952 goto return_unref; 02953 02954 /* if the peer is being monitored and is currently unreachable, return failure */ 02955 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 02956 goto return_unref; 02957 02958 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 02959 cai->maxtime = peer->maxms; 02960 cai->capability = peer->capability; 02961 cai->encmethods = peer->encmethods; 02962 cai->sockfd = peer->sockfd; 02963 cai->adsi = peer->adsi; 02964 ast_codec_pref_convert(&peer->prefs, cai->prefs, sizeof(cai->prefs), 1); 02965 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 02966 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 02967 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 02968 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 02969 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 02970 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 02971 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 02972 if (ast_strlen_zero(peer->dbsecret)) { 02973 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 02974 } else { 02975 char *family; 02976 char *key = NULL; 02977 02978 family = ast_strdupa(peer->dbsecret); 02979 key = strchr(family, '/'); 02980 if (key) 02981 *key++ = '\0'; 02982 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 02983 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 02984 goto return_unref; 02985 } 02986 } 02987 02988 if (peer->addr.sin_addr.s_addr) { 02989 sin->sin_addr = peer->addr.sin_addr; 02990 sin->sin_port = peer->addr.sin_port; 02991 } else { 02992 sin->sin_addr = peer->defaddr.sin_addr; 02993 sin->sin_port = peer->defaddr.sin_port; 02994 } 02995 02996 res = 0; 02997 02998 return_unref: 02999 peer_unref(peer); 03000 03001 return res; 03002 }
static int decode_frame | ( | aes_decrypt_ctx * | dcx, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 4023 of file chan_iax2.c.
References AST_FRAME_VIDEO, ast_log(), ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, ast_frame::frametype, IAX_FLAG_FULL, LOG_DEBUG, memcpy_decrypt(), option_debug, ast_iax2_full_hdr::scallno, ast_frame::subclass, ast_iax2_full_hdr::type, and uncompress_subclass().
Referenced by decrypt_frame().
04024 { 04025 int padding; 04026 unsigned char *workspace; 04027 04028 workspace = alloca(*datalen); 04029 memset(f, 0, sizeof(*f)); 04030 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 04031 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 04032 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 04033 return -1; 04034 /* Decrypt */ 04035 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 04036 04037 padding = 16 + (workspace[15] & 0xf); 04038 if (option_debug && iaxdebug) 04039 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 04040 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 04041 return -1; 04042 04043 *datalen -= padding; 04044 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 04045 f->frametype = fh->type; 04046 if (f->frametype == AST_FRAME_VIDEO) { 04047 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 04048 } else { 04049 f->subclass = uncompress_subclass(fh->csub); 04050 } 04051 } else { 04052 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 04053 if (option_debug && iaxdebug) 04054 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen); 04055 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 04056 return -1; 04057 /* Decrypt */ 04058 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 04059 padding = 16 + (workspace[15] & 0x0f); 04060 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 04061 return -1; 04062 *datalen -= padding; 04063 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04064 } 04065 return 0; 04066 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 4109 of file chan_iax2.c.
References ast_set_flag, ast_strdupa, ast_test_flag, build_enc_keys(), decode_frame(), IAX_KEYPOPULATED, iaxs, MD5Final(), MD5Init(), MD5Update(), iax2_registry::secret, and strsep().
Referenced by socket_process().
04110 { 04111 int res=-1; 04112 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 04113 /* Search for possible keys, given secrets */ 04114 struct MD5Context md5; 04115 unsigned char digest[16]; 04116 char *tmppw, *stringp; 04117 04118 tmppw = ast_strdupa(iaxs[callno]->secret); 04119 stringp = tmppw; 04120 while ((tmppw = strsep(&stringp, ";"))) { 04121 MD5Init(&md5); 04122 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 04123 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 04124 MD5Final(digest, &md5); 04125 build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx); 04126 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04127 if (!res) { 04128 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 04129 break; 04130 } 04131 } 04132 } else 04133 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04134 return res; 04135 }
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 6703 of file chan_iax2.c.
References ast_calloc, AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock(), ast_mutex_unlock(), and ast_iax2_full_hdr::oseqno.
Referenced by socket_read().
06704 { 06705 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 06706 struct ast_iax2_full_hdr *fh, *cur_fh; 06707 06708 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 06709 return; 06710 06711 pkt_buf->len = from_here->buf_len; 06712 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 06713 06714 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 06715 ast_mutex_lock(&to_here->lock); 06716 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 06717 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 06718 if (fh->oseqno < cur_fh->oseqno) { 06719 AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry); 06720 break; 06721 } 06722 } 06723 AST_LIST_TRAVERSE_SAFE_END 06724 06725 if (!cur_pkt_buf) 06726 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 06727 06728 ast_mutex_unlock(&to_here->lock); 06729 }
static void delete_users | ( | void | ) | [static] |
Definition at line 9584 of file chan_iax2.c.
References ao2_callback(), ast_dnsmgr_release(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, free, iax2_destroy(), iaxs, iaxsl, peer_delme_cb(), peers, chan_iax2_pvt::reg, user_delme_cb(), and users.
09585 { 09586 struct iax2_registry *reg; 09587 09588 ao2_callback(users, 0, user_delme_cb, NULL); 09589 09590 AST_LIST_LOCK(®istrations); 09591 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 09592 if (reg->expire > -1) 09593 ast_sched_del(sched, reg->expire); 09594 if (reg->callno) { 09595 ast_mutex_lock(&iaxsl[reg->callno]); 09596 if (iaxs[reg->callno]) { 09597 iaxs[reg->callno]->reg = NULL; 09598 iax2_destroy(reg->callno); 09599 } 09600 ast_mutex_unlock(&iaxsl[reg->callno]); 09601 } 09602 if (reg->dnsmgr) 09603 ast_dnsmgr_release(reg->dnsmgr); 09604 free(reg); 09605 } 09606 AST_LIST_UNLOCK(®istrations); 09607 09608 ao2_callback(peers, 0, peer_delme_cb, NULL); 09609 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 1546 of file chan_iax2.c.
References ast_iax2_firmware_header::datalen, iax_firmware::fd, free, and iax_firmware::fwh.
Referenced by reload_firmware().
01547 { 01548 /* Close firmware */ 01549 if (cur->fwh) { 01550 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 01551 } 01552 close(cur->fd); 01553 free(cur); 01554 }
static void dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 6475 of file chan_iax2.c.
References ast_canmatch_extension(), ast_exists_extension(), AST_FRAME_IAX, ast_ignore_pattern(), ast_matchmore_extension(), ast_mutex_lock(), ast_mutex_unlock(), ast_parking_ext(), iax_ie_data::buf, IAX_COMMAND_DPREP, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_NUMBER, IAX_IE_DPSTATUS, IAX_IE_REFRESH, iaxs, iaxsl, iax_ie_data::pos, and send_command().
Referenced by dp_lookup_thread(), and socket_process().
06476 { 06477 unsigned short dpstatus = 0; 06478 struct iax_ie_data ied1; 06479 int mm; 06480 06481 memset(&ied1, 0, sizeof(ied1)); 06482 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 06483 /* Must be started */ 06484 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 06485 dpstatus = IAX_DPSTATUS_EXISTS; 06486 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 06487 dpstatus = IAX_DPSTATUS_CANEXIST; 06488 } else { 06489 dpstatus = IAX_DPSTATUS_NONEXISTENT; 06490 } 06491 if (ast_ignore_pattern(context, callednum)) 06492 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 06493 if (mm) 06494 dpstatus |= IAX_DPSTATUS_MATCHMORE; 06495 if (!skiplock) 06496 ast_mutex_lock(&iaxsl[callno]); 06497 if (iaxs[callno]) { 06498 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 06499 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 06500 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 06501 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 06502 } 06503 if (!skiplock) 06504 ast_mutex_unlock(&iaxsl[callno]); 06505 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 6507 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().
06508 { 06509 /* Look up for dpreq */ 06510 struct dpreq_data *dpr = data; 06511 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 06512 if (dpr->callerid) 06513 free(dpr->callerid); 06514 free(dpr); 06515 return NULL; 06516 }
static int encrypt_frame | ( | aes_encrypt_ctx * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 4068 of file chan_iax2.c.
References ast_log(), ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, IAX_FLAG_FULL, LOG_DEBUG, memcpy_encrypt(), option_debug, ast_iax2_full_hdr::scallno, and ast_iax2_full_hdr::type.
Referenced by iax2_send().
04069 { 04070 int padding; 04071 unsigned char *workspace; 04072 workspace = alloca(*datalen + 32); 04073 if (!workspace) 04074 return -1; 04075 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 04076 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 04077 if (option_debug && iaxdebug) 04078 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 04079 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 04080 padding = 16 + (padding & 0xf); 04081 memcpy(workspace, poo, padding); 04082 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 04083 workspace[15] &= 0xf0; 04084 workspace[15] |= (padding & 0xf); 04085 if (option_debug && iaxdebug) 04086 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]); 04087 *datalen += padding; 04088 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 04089 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 04090 memcpy(poo, workspace + *datalen - 32, 32); 04091 } else { 04092 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 04093 if (option_debug && iaxdebug) 04094 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen); 04095 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 04096 padding = 16 + (padding & 0xf); 04097 memcpy(workspace, poo, padding); 04098 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04099 workspace[15] &= 0xf0; 04100 workspace[15] |= (padding & 0x0f); 04101 *datalen += padding; 04102 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 04103 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 04104 memcpy(poo, workspace + *datalen - 32, 32); 04105 } 04106 return 0; 04107 }
static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 5921 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by iax2_prune_realtime(), realtime_peer(), reg_source_db(), and update_registry().
05922 { 05923 #ifdef SCHED_MULTITHREADED 05924 if (schedule_action(__expire_registry, data)) 05925 #endif 05926 __expire_registry(data); 05927 return 0; 05928 }
static struct iax2_dpcache* find_cache | ( | struct ast_channel * | chan, | |
const char * | data, | |||
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) | [static, read] |
Definition at line 10139 of file chan_iax2.c.
References ast_calloc, ast_channel_defer_dtmf(), ast_channel_undefer_dtmf(), ast_frfree, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_read(), ast_test_flag, ast_waitfor_nandfds(), CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, cache_get_callno_locked(), iax2_dpcache::callno, iax2_registry::callno, dpcache, chan_iax2_pvt::dpentries, iax2_dpcache::expiry, iax2_dpcache::exten, f, iax2_dpcache::flags, free, iax2_dprequest(), IAX_STATE_STARTED, iaxs, iaxsl, LOG_WARNING, iax2_dpcache::next, iax2_dpcache::orig, iax2_dpcache::peer, iax2_dpcache::peercontext, and iax2_dpcache::waiters.
Referenced by iax2_canmatch(), iax2_exec(), iax2_exists(), and iax2_matchmore().
10140 { 10141 struct iax2_dpcache *dp, *prev = NULL, *next; 10142 struct timeval tv; 10143 int x; 10144 int com[2]; 10145 int timeout; 10146 int old=0; 10147 int outfd; 10148 int abort; 10149 int callno; 10150 struct ast_channel *c; 10151 struct ast_frame *f; 10152 gettimeofday(&tv, NULL); 10153 dp = dpcache; 10154 while(dp) { 10155 next = dp->next; 10156 /* Expire old caches */ 10157 if (ast_tvcmp(tv, dp->expiry) > 0) { 10158 /* It's expired, let it disappear */ 10159 if (prev) 10160 prev->next = dp->next; 10161 else 10162 dpcache = dp->next; 10163 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) { 10164 /* Free memory and go again */ 10165 free(dp); 10166 } else { 10167 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); 10168 } 10169 dp = next; 10170 continue; 10171 } 10172 /* We found an entry that matches us! */ 10173 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 10174 break; 10175 prev = dp; 10176 dp = next; 10177 } 10178 if (!dp) { 10179 /* No matching entry. Create a new one. */ 10180 /* First, can we make a callno? */ 10181 callno = cache_get_callno_locked(data); 10182 if (callno < 0) { 10183 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 10184 return NULL; 10185 } 10186 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 10187 ast_mutex_unlock(&iaxsl[callno]); 10188 return NULL; 10189 } 10190 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 10191 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 10192 gettimeofday(&dp->expiry, NULL); 10193 dp->orig = dp->expiry; 10194 /* Expires in 30 mins by default */ 10195 dp->expiry.tv_sec += iaxdefaultdpcache; 10196 dp->next = dpcache; 10197 dp->flags = CACHE_FLAG_PENDING; 10198 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 10199 dp->waiters[x] = -1; 10200 dpcache = dp; 10201 dp->peer = iaxs[callno]->dpentries; 10202 iaxs[callno]->dpentries = dp; 10203 /* Send the request if we're already up */ 10204 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 10205 iax2_dprequest(dp, callno); 10206 ast_mutex_unlock(&iaxsl[callno]); 10207 } 10208 /* By here we must have a dp */ 10209 if (dp->flags & CACHE_FLAG_PENDING) { 10210 /* Okay, here it starts to get nasty. We need a pipe now to wait 10211 for a reply to come back so long as it's pending */ 10212 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) { 10213 /* Find an empty slot */ 10214 if (dp->waiters[x] < 0) 10215 break; 10216 } 10217 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) { 10218 ast_log(LOG_WARNING, "No more waiter positions available\n"); 10219 return NULL; 10220 } 10221 if (pipe(com)) { 10222 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 10223 return NULL; 10224 } 10225 dp->waiters[x] = com[1]; 10226 /* Okay, now we wait */ 10227 timeout = iaxdefaulttimeout * 1000; 10228 /* Temporarily unlock */ 10229 ast_mutex_unlock(&dpcache_lock); 10230 /* Defer any dtmf */ 10231 if (chan) 10232 old = ast_channel_defer_dtmf(chan); 10233 abort = 0; 10234 while(timeout) { 10235 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 10236 if (outfd > -1) { 10237 break; 10238 } 10239 if (c) { 10240 f = ast_read(c); 10241 if (f) 10242 ast_frfree(f); 10243 else { 10244 /* Got hung up on, abort! */ 10245 break; 10246 abort = 1; 10247 } 10248 } 10249 } 10250 if (!timeout) { 10251 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 10252 } 10253 ast_mutex_lock(&dpcache_lock); 10254 dp->waiters[x] = -1; 10255 close(com[1]); 10256 close(com[0]); 10257 if (abort) { 10258 /* Don't interpret anything, just abort. Not sure what th epoint 10259 of undeferring dtmf on a hung up channel is but hey whatever */ 10260 if (!old && chan) 10261 ast_channel_undefer_dtmf(chan); 10262 return NULL; 10263 } 10264 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 10265 /* Now to do non-independent analysis the results of our wait */ 10266 if (dp->flags & CACHE_FLAG_PENDING) { 10267 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 10268 pending. Don't let it take as long to timeout. */ 10269 dp->flags &= ~CACHE_FLAG_PENDING; 10270 dp->flags |= CACHE_FLAG_TIMEOUT; 10271 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 10272 systems without leaving it unavailable once the server comes back online */ 10273 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 10274 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 10275 if (dp->waiters[x] > -1) 10276 write(dp->waiters[x], "asdf", 4); 10277 } 10278 } 10279 /* Our caller will obtain the rest */ 10280 if (!old && chan) 10281 ast_channel_undefer_dtmf(chan); 10282 } 10283 return dp; 10284 }
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 1344 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::amaflags, ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_string_field_set, chan_iax2_pvt::callno, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, iax2_getpeername(), iax2_sched_add(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, iaxs, iaxsl, chan_iax2_pvt::lagid, lastused, LOG_DEBUG, LOG_WARNING, match(), MIN_REUSE_TIME, NEW_ALLOW, new_iax(), option_debug, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingid, chan_iax2_pvt::pingtime, send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, TRUNK_CALL_START, and update_max_nontrunk().
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_poke_peer(), iax2_provision(), iax2_request(), and socket_process().
01345 { 01346 int res = 0; 01347 int x; 01348 struct timeval now; 01349 char host[80]; 01350 01351 if (new <= NEW_ALLOW) { 01352 /* Look for an existing connection first */ 01353 for (x=1;(res < 1) && (x<maxnontrunkcall);x++) { 01354 ast_mutex_lock(&iaxsl[x]); 01355 if (iaxs[x]) { 01356 /* Look for an exact match */ 01357 if (match(sin, callno, dcallno, iaxs[x], full_frame)) { 01358 res = x; 01359 } 01360 } 01361 ast_mutex_unlock(&iaxsl[x]); 01362 } 01363 for (x=TRUNK_CALL_START;(res < 1) && (x<maxtrunkcall);x++) { 01364 ast_mutex_lock(&iaxsl[x]); 01365 if (iaxs[x]) { 01366 /* Look for an exact match */ 01367 if (match(sin, callno, dcallno, iaxs[x], full_frame)) { 01368 res = x; 01369 } 01370 } 01371 ast_mutex_unlock(&iaxsl[x]); 01372 } 01373 } 01374 if ((res < 1) && (new >= NEW_ALLOW)) { 01375 int start, found = 0; 01376 01377 /* It may seem odd that we look through the peer list for a name for 01378 * this *incoming* call. Well, it is weird. However, users don't 01379 * have an IP address/port number that we can match against. So, 01380 * this is just checking for a peer that has that IP/port and 01381 * assuming that we have a user of the same name. This isn't always 01382 * correct, but it will be changed if needed after authentication. */ 01383 if (!iax2_getpeername(*sin, host, sizeof(host))) 01384 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 01385 01386 now = ast_tvnow(); 01387 start = 2 + (ast_random() % (TRUNK_CALL_START - 1)); 01388 for (x = start; 1; x++) { 01389 if (x == TRUNK_CALL_START) { 01390 x = 1; 01391 continue; 01392 } 01393 01394 /* Find first unused call number that hasn't been used in a while */ 01395 ast_mutex_lock(&iaxsl[x]); 01396 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01397 found = 1; 01398 break; 01399 } 01400 ast_mutex_unlock(&iaxsl[x]); 01401 01402 if (x == start - 1) { 01403 break; 01404 } 01405 } 01406 /* We've still got lock held if we found a spot */ 01407 if (x == start - 1 && !found) { 01408 ast_log(LOG_WARNING, "No more space\n"); 01409 return 0; 01410 } 01411 iaxs[x] = new_iax(sin, host); 01412 update_max_nontrunk(); 01413 if (iaxs[x]) { 01414 if (option_debug && iaxdebug) 01415 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x); 01416 iaxs[x]->sockfd = sockfd; 01417 iaxs[x]->addr.sin_port = sin->sin_port; 01418 iaxs[x]->addr.sin_family = sin->sin_family; 01419 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 01420 iaxs[x]->peercallno = callno; 01421 iaxs[x]->callno = x; 01422 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 01423 iaxs[x]->expiry = min_reg_expire; 01424 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01425 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01426 iaxs[x]->amaflags = amaflags; 01427 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 01428 01429 ast_string_field_set(iaxs[x], accountcode, accountcode); 01430 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 01431 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 01432 } else { 01433 ast_log(LOG_WARNING, "Out of resources\n"); 01434 ast_mutex_unlock(&iaxsl[x]); 01435 return 0; 01436 } 01437 ast_mutex_unlock(&iaxsl[x]); 01438 res = x; 01439 } 01440 return res; 01441 }
static struct iax2_thread* find_idle_thread | ( | void | ) | [static, read] |
Definition at line 895 of file chan_iax2.c.
References ast_calloc, ast_cond_init(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_init(), ast_pthread_create, iax2_thread::ffinfo, free, iax2_process_thread(), IAX_TYPE_DYNAMIC, iaxdynamicthreadcount, iaxmaxthreadcount, and thread.
Referenced by __schedule_action(), and socket_read().
00896 { 00897 pthread_attr_t attr; 00898 struct iax2_thread *thread = NULL; 00899 00900 /* Pop the head of the list off */ 00901 AST_LIST_LOCK(&idle_list); 00902 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 00903 AST_LIST_UNLOCK(&idle_list); 00904 00905 /* If no idle thread is available from the regular list, try dynamic */ 00906 if (thread == NULL) { 00907 AST_LIST_LOCK(&dynamic_list); 00908 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 00909 /* Make sure we absolutely have a thread... if not, try to make one if allowed */ 00910 if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) { 00911 /* We need to MAKE a thread! */ 00912 if ((thread = ast_calloc(1, sizeof(*thread)))) { 00913 thread->threadnum = iaxdynamicthreadcount; 00914 thread->type = IAX_TYPE_DYNAMIC; 00915 ast_mutex_init(&thread->lock); 00916 ast_cond_init(&thread->cond, NULL); 00917 pthread_attr_init(&attr); 00918 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 00919 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 00920 free(thread); 00921 thread = NULL; 00922 } else { 00923 /* All went well and the thread is up, so increment our count */ 00924 iaxdynamicthreadcount++; 00925 00926 /* Wait for the thread to be ready before returning it to the caller */ 00927 while (!thread->ready_for_signal) 00928 usleep(1); 00929 } 00930 } 00931 } 00932 AST_LIST_UNLOCK(&dynamic_list); 00933 } 00934 00935 /* this thread is not processing a full frame (since it is idle), 00936 so ensure that the field for the full frame call number is empty */ 00937 if (thread) 00938 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 00939 00940 return thread; 00941 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static, read] |
Definition at line 1117 of file chan_iax2.c.
References ao2_find(), peers, and realtime_peer().
01118 { 01119 struct iax2_peer *peer = NULL; 01120 struct iax2_peer tmp_peer = { 01121 .name = name, 01122 }; 01123 01124 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01125 01126 /* Now go for realtime if applicable */ 01127 if(!peer && realtime) 01128 peer = realtime_peer(name, NULL); 01129 01130 return peer; 01131 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static, read] |
Definition at line 3877 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_calloc, ast_inet_ntoa(), ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), inaddrcmp(), iax2_trunk_peer::lastsent, iax2_trunk_peer::lock, LOG_DEBUG, iax2_trunk_peer::next, option_debug, iax2_trunk_peer::sockfd, tpeers, and iax2_trunk_peer::trunkact.
Referenced by iax2_trunk_queue(), and socket_process().
03878 { 03879 struct iax2_trunk_peer *tpeer; 03880 03881 /* Finds and locks trunk peer */ 03882 ast_mutex_lock(&tpeerlock); 03883 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) { 03884 /* We don't lock here because tpeer->addr *never* changes */ 03885 if (!inaddrcmp(&tpeer->addr, sin)) { 03886 ast_mutex_lock(&tpeer->lock); 03887 break; 03888 } 03889 } 03890 if (!tpeer) { 03891 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 03892 ast_mutex_init(&tpeer->lock); 03893 tpeer->lastsent = 9999; 03894 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 03895 tpeer->trunkact = ast_tvnow(); 03896 ast_mutex_lock(&tpeer->lock); 03897 tpeer->next = tpeers; 03898 tpeer->sockfd = fd; 03899 tpeers = tpeer; 03900 #ifdef SO_NO_CHECK 03901 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 03902 #endif 03903 if (option_debug) 03904 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 03905 } 03906 } 03907 ast_mutex_unlock(&tpeerlock); 03908 return tpeer; 03909 }
static unsigned int fix_peerts | ( | struct timeval * | tv, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 3704 of file chan_iax2.c.
References iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process().
03705 { 03706 long ms; /* NOT unsigned */ 03707 if (ast_tvzero(iaxs[callno]->rxcore)) { 03708 /* Initialize rxcore time if appropriate */ 03709 gettimeofday(&iaxs[callno]->rxcore, NULL); 03710 /* Round to nearest 20ms so traces look pretty */ 03711 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 03712 } 03713 /* Calculate difference between trunk and channel */ 03714 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore); 03715 /* Return as the sum of trunk time and the difference between trunk and real time */ 03716 return ms + ts; 03717 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 8746 of file chan_iax2.c.
References free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
08747 { 08748 struct iax2_context *conl; 08749 while(con) { 08750 conl = con; 08751 con = con->next; 08752 free(conl); 08753 } 08754 }
static int function_iaxpeer | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 10408 of file chan_iax2.c.
References iax2_peer::addr, iax2_registry::addr, ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strdupa, ast_test_flag, iax2_registry::callno, iax2_peer::capability, iax2_peer::expire, find_peer(), iax2_tech, IAX_DYNAMIC, iaxs, peer_status(), peer_unref(), iax2_peer::prefs, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.
10409 { 10410 struct iax2_peer *peer; 10411 char *peername, *colname; 10412 10413 peername = ast_strdupa(data); 10414 10415 /* if our channel, return the IP address of the endpoint of current channel */ 10416 if (!strcmp(peername,"CURRENTCHANNEL")) { 10417 unsigned short callno; 10418 if (chan->tech != &iax2_tech) 10419 return -1; 10420 callno = PTR_TO_CALLNO(chan->tech_pvt); 10421 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 10422 return 0; 10423 } 10424 10425 if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */ 10426 *colname++ = '\0'; 10427 else if ((colname = strchr(peername, '|'))) 10428 *colname++ = '\0'; 10429 else 10430 colname = "ip"; 10431 10432 if (!(peer = find_peer(peername, 1))) 10433 return -1; 10434 10435 if (!strcasecmp(colname, "ip")) { 10436 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 10437 } else if (!strcasecmp(colname, "status")) { 10438 peer_status(peer, buf, len); 10439 } else if (!strcasecmp(colname, "mailbox")) { 10440 ast_copy_string(buf, peer->mailbox, len); 10441 } else if (!strcasecmp(colname, "context")) { 10442 ast_copy_string(buf, peer->context, len); 10443 } else if (!strcasecmp(colname, "expire")) { 10444 snprintf(buf, len, "%d", peer->expire); 10445 } else if (!strcasecmp(colname, "dynamic")) { 10446 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 10447 } else if (!strcasecmp(colname, "callerid_name")) { 10448 ast_copy_string(buf, peer->cid_name, len); 10449 } else if (!strcasecmp(colname, "callerid_num")) { 10450 ast_copy_string(buf, peer->cid_num, len); 10451 } else if (!strcasecmp(colname, "codecs")) { 10452 ast_getformatname_multiple(buf, len -1, peer->capability); 10453 } else if (!strncasecmp(colname, "codec[", 6)) { 10454 char *codecnum, *ptr; 10455 int index = 0, codec = 0; 10456 10457 codecnum = strchr(colname, '['); 10458 *codecnum = '\0'; 10459 codecnum++; 10460 if ((ptr = strchr(codecnum, ']'))) { 10461 *ptr = '\0'; 10462 } 10463 index = atoi(codecnum); 10464 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 10465 ast_copy_string(buf, ast_getformatname(codec), len); 10466 } 10467 } 10468 10469 peer_unref(peer); 10470 10471 return 0; 10472 }
static int get_auth_methods | ( | char * | value | ) | [static] |
Definition at line 8974 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
08975 { 08976 int methods = 0; 08977 if (strstr(value, "rsa")) 08978 methods |= IAX_AUTH_RSA; 08979 if (strstr(value, "md5")) 08980 methods |= IAX_AUTH_MD5; 08981 if (strstr(value, "plaintext")) 08982 methods |= IAX_AUTH_PLAINTEXT; 08983 return methods; 08984 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1004 of file chan_iax2.c.
References ast_true(), and IAX_ENCRYPT_AES128.
Referenced by build_peer(), build_user(), and set_config().
01005 { 01006 int e; 01007 if (!strcasecmp(s, "aes128")) 01008 e = IAX_ENCRYPT_AES128; 01009 else if (ast_true(s)) 01010 e = IAX_ENCRYPT_AES128; 01011 else 01012 e = 0; 01013 return e; 01014 }
static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 2534 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
02535 { 02536 #ifdef SCHED_MULTITHREADED 02537 if (schedule_action(__get_from_jb, data)) 02538 #endif 02539 __get_from_jb(data); 02540 return 0; 02541 }
static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 6673 of file chan_iax2.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), and socket_process().
Referenced by iax2_process_thread().
06674 { 06675 struct iax2_pkt_buf *pkt_buf; 06676 06677 ast_mutex_lock(&thread->lock); 06678 06679 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 06680 ast_mutex_unlock(&thread->lock); 06681 06682 thread->buf = pkt_buf->buf; 06683 thread->buf_len = pkt_buf->len; 06684 thread->buf_size = pkt_buf->len + 1; 06685 06686 socket_process(thread); 06687 06688 thread->buf = NULL; 06689 ast_free(pkt_buf); 06690 06691 ast_mutex_lock(&thread->lock); 06692 } 06693 06694 ast_mutex_unlock(&thread->lock); 06695 }
static int handle_error | ( | void | ) | [static] |
Definition at line 1834 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().
01835 { 01836 /* XXX Ideally we should figure out why an error occured and then abort those 01837 rather than continuing to try. Unfortunately, the published interface does 01838 not seem to work XXX */ 01839 #if 0 01840 struct sockaddr_in *sin; 01841 int res; 01842 struct msghdr m; 01843 struct sock_extended_err e; 01844 m.msg_name = NULL; 01845 m.msg_namelen = 0; 01846 m.msg_iov = NULL; 01847 m.msg_control = &e; 01848 m.msg_controllen = sizeof(e); 01849 m.msg_flags = 0; 01850 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 01851 if (res < 0) 01852 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 01853 else { 01854 if (m.msg_controllen) { 01855 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 01856 if (sin) 01857 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 01858 else 01859 ast_log(LOG_WARNING, "No address detected??\n"); 01860 } else { 01861 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 01862 } 01863 } 01864 #endif 01865 return 0; 01866 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 5741 of file chan_iax2.c.
References iax2_registry::addr, iax_ies::apparent_addr, ast_inet_ntoa(), ast_log(), ast_sched_del(), ast_verbose(), iax_ies::calling_number, EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), iax2_sched_add(), iaxs, inaddrcmp(), LOG_WARNING, manager_event(), iax2_registry::messages, iax_ies::msgcount, option_verbose, iax_ies::refresh, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGISTERED, iax2_registry::regstate, iax2_registry::us, iax_ies::username, and VERBOSE_PREFIX_3.
Referenced by socket_process().
05742 { 05743 struct iax2_registry *reg; 05744 /* Start pessimistic */ 05745 char peer[256] = ""; 05746 char msgstatus[60]; 05747 int refresh = 60; 05748 char ourip[256] = "<Unspecified>"; 05749 struct sockaddr_in oldus; 05750 struct sockaddr_in us; 05751 int oldmsgs; 05752 05753 memset(&us, 0, sizeof(us)); 05754 if (ies->apparent_addr) 05755 bcopy(ies->apparent_addr, &us, sizeof(us)); 05756 if (ies->username) 05757 ast_copy_string(peer, ies->username, sizeof(peer)); 05758 if (ies->refresh) 05759 refresh = ies->refresh; 05760 if (ies->calling_number) { 05761 /* We don't do anything with it really, but maybe we should */ 05762 } 05763 reg = iaxs[callno]->reg; 05764 if (!reg) { 05765 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 05766 return -1; 05767 } 05768 memcpy(&oldus, ®->us, sizeof(oldus)); 05769 oldmsgs = reg->messages; 05770 if (inaddrcmp(®->addr, sin)) { 05771 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 05772 return -1; 05773 } 05774 memcpy(®->us, &us, sizeof(reg->us)); 05775 if (ies->msgcount >= 0) 05776 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 05777 /* always refresh the registration at the interval requested by the server 05778 we are registering to 05779 */ 05780 reg->refresh = refresh; 05781 if (reg->expire > -1) 05782 ast_sched_del(sched, reg->expire); 05783 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 05784 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 05785 if (option_verbose > 2) { 05786 if (reg->messages > 255) 05787 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 05788 else if (reg->messages > 1) 05789 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages); 05790 else if (reg->messages > 0) 05791 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n"); 05792 else 05793 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n"); 05794 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 05795 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 05796 } 05797 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 05798 } 05799 reg->regstate = REG_STATE_REGISTERED; 05800 return 0; 05801 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3525 of file chan_iax2.c.
References AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_log(), iax2_registry::callno, LOG_DEBUG, option_debug, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03526 { 03527 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03528 if (option_debug) 03529 ast_log(LOG_DEBUG, "Answering IAX2 call\n"); 03530 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 03531 }
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 3375 of file chan_iax2.c.
References ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_IGNORE_SIGS, AST_BRIDGE_RETRY, ast_check_hangup(), AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_IMAGE, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_read(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_verbose(), ast_waitfor_n(), ast_write(), chan_iax2_pvt::bridgecallno, f, ast_frame::frametype, iax2_start_transfer(), iax2_tech, IAX_LINGER_TIMEOUT, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, iaxs, iaxsl, lock_both(), LOG_WARNING, ast_channel::nativeformats, option_verbose, PTR_TO_CALLNO, ast_channel::tech, ast_channel::tech_pvt, TRANSFER_RELEASED, tv, unlock_both(), and VERBOSE_PREFIX_3.
03376 { 03377 struct ast_channel *cs[3]; 03378 struct ast_channel *who, *other; 03379 int to = -1; 03380 int res = -1; 03381 int transferstarted=0; 03382 struct ast_frame *f; 03383 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 03384 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 03385 struct timeval waittimer = {0, 0}, tv; 03386 03387 lock_both(callno0, callno1); 03388 if (!iaxs[callno0] || !iaxs[callno1]) { 03389 unlock_both(callno0, callno1); 03390 return AST_BRIDGE_FAILED; 03391 } 03392 /* Put them in native bridge mode */ 03393 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) { 03394 iaxs[callno0]->bridgecallno = callno1; 03395 iaxs[callno1]->bridgecallno = callno0; 03396 } 03397 unlock_both(callno0, callno1); 03398 03399 /* If not, try to bridge until we can execute a transfer, if we can */ 03400 cs[0] = c0; 03401 cs[1] = c1; 03402 for (/* ever */;;) { 03403 /* Check in case we got masqueraded into */ 03404 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 03405 if (option_verbose > 2) 03406 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n"); 03407 /* Remove from native mode */ 03408 if (c0->tech == &iax2_tech) { 03409 ast_mutex_lock(&iaxsl[callno0]); 03410 iaxs[callno0]->bridgecallno = 0; 03411 ast_mutex_unlock(&iaxsl[callno0]); 03412 } 03413 if (c1->tech == &iax2_tech) { 03414 ast_mutex_lock(&iaxsl[callno1]); 03415 iaxs[callno1]->bridgecallno = 0; 03416 ast_mutex_unlock(&iaxsl[callno1]); 03417 } 03418 return AST_BRIDGE_FAILED_NOWARN; 03419 } 03420 if (c0->nativeformats != c1->nativeformats) { 03421 if (option_verbose > 2) { 03422 char buf0[255]; 03423 char buf1[255]; 03424 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 03425 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 03426 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 03427 } 03428 /* Remove from native mode */ 03429 lock_both(callno0, callno1); 03430 if (iaxs[callno0]) 03431 iaxs[callno0]->bridgecallno = 0; 03432 if (iaxs[callno1]) 03433 iaxs[callno1]->bridgecallno = 0; 03434 unlock_both(callno0, callno1); 03435 return AST_BRIDGE_FAILED_NOWARN; 03436 } 03437 /* check if transfered and if we really want native bridging */ 03438 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) { 03439 /* Try the transfer */ 03440 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 03441 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA))) 03442 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 03443 transferstarted = 1; 03444 } 03445 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 03446 /* Call has been transferred. We're no longer involved */ 03447 gettimeofday(&tv, NULL); 03448 if (ast_tvzero(waittimer)) { 03449 waittimer = tv; 03450 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 03451 c0->_softhangup |= AST_SOFTHANGUP_DEV; 03452 c1->_softhangup |= AST_SOFTHANGUP_DEV; 03453 *fo = NULL; 03454 *rc = c0; 03455 res = AST_BRIDGE_COMPLETE; 03456 break; 03457 } 03458 } 03459 to = 1000; 03460 who = ast_waitfor_n(cs, 2, &to); 03461 if (timeoutms > -1) { 03462 timeoutms -= (1000 - to); 03463 if (timeoutms < 0) 03464 timeoutms = 0; 03465 } 03466 if (!who) { 03467 if (!timeoutms) { 03468 res = AST_BRIDGE_RETRY; 03469 break; 03470 } 03471 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 03472 res = AST_BRIDGE_FAILED; 03473 break; 03474 } 03475 continue; 03476 } 03477 f = ast_read(who); 03478 if (!f) { 03479 *fo = NULL; 03480 *rc = who; 03481 res = AST_BRIDGE_COMPLETE; 03482 break; 03483 } 03484 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 03485 *fo = f; 03486 *rc = who; 03487 res = AST_BRIDGE_COMPLETE; 03488 break; 03489 } 03490 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 03491 if ((f->frametype == AST_FRAME_VOICE) || 03492 (f->frametype == AST_FRAME_TEXT) || 03493 (f->frametype == AST_FRAME_VIDEO) || 03494 (f->frametype == AST_FRAME_IMAGE) || 03495 (f->frametype == AST_FRAME_DTMF)) { 03496 /* monitored dtmf take out of the bridge. 03497 * check if we monitor the specific source. 03498 */ 03499 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 03500 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 03501 *rc = who; 03502 *fo = f; 03503 res = AST_BRIDGE_COMPLETE; 03504 /* Remove from native mode */ 03505 break; 03506 } 03507 /* everything else goes to the other side */ 03508 ast_write(other, f); 03509 } 03510 ast_frfree(f); 03511 /* Swap who gets priority */ 03512 cs[2] = cs[0]; 03513 cs[0] = cs[1]; 03514 cs[1] = cs[2]; 03515 } 03516 lock_both(callno0, callno1); 03517 if(iaxs[callno0]) 03518 iaxs[callno0]->bridgecallno = 0; 03519 if(iaxs[callno1]) 03520 iaxs[callno1]->bridgecallno = 0; 03521 unlock_both(callno0, callno1); 03522 return res; 03523 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 3123 of file chan_iax2.c.
References ast_channel::_state, create_addr_info::adsi, chan_iax2_pvt::adsi, ast_channel::adsicpe, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PRES_NUMBER_NOT_AVAILABLE, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, auto_congest(), iax_ie_data::buf, iax2_registry::callno, CALLNO_TO_PTR, capability, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, create_addr_info::context, ast_channel::context, parsed_dial_string::context, create_addr(), chan_iax2_pvt::encmethods, create_addr_info::encmethods, parsed_dial_string::exten, iax2_datetime(), iax2_sched_add(), IAX_COMMAND_NEW, IAX_IE_ADSICPE, iax_ie_append(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTOANSWER, IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CALLING_ANI, IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_CALLINGPRES, IAX_IE_CALLINGTNS, IAX_IE_CALLINGTON, IAX_IE_CAPABILITY, IAX_IE_CODEC_PREFS, IAX_IE_DATETIME, IAX_IE_DNID, IAX_IE_ENCRYPTION, IAX_IE_FORMAT, IAX_IE_LANGUAGE, IAX_IE_RDNIS, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, IAX_SENDANI, iaxs, iaxsl, chan_iax2_pvt::initid, parsed_dial_string::key, LOG_WARNING, chan_iax2_pvt::maxtime, create_addr_info::maxtime, create_addr_info::mohinterpret, create_addr_info::mohsuggest, ast_channel::nativeformats, parsed_dial_string::options, create_addr_info::outkey, parse_dial_string(), parsed_dial_string::password, parsed_dial_string::peer, create_addr_info::peercontext, chan_iax2_pvt::pingtime, parsed_dial_string::port, iax_ie_data::pos, create_addr_info::prefs, PTR_TO_CALLNO, iax2_registry::secret, create_addr_info::secret, send_command(), create_addr_info::sockfd, chan_iax2_pvt::sockfd, ast_channel::tech_pvt, create_addr_info::timezone, create_addr_info::username, and parsed_dial_string::username.
03124 { 03125 struct sockaddr_in sin; 03126 char *l=NULL, *n=NULL, *tmpstr; 03127 struct iax_ie_data ied; 03128 char *defaultrdest = "s"; 03129 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03130 struct parsed_dial_string pds; 03131 struct create_addr_info cai; 03132 03133 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 03134 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 03135 return -1; 03136 } 03137 03138 memset(&cai, 0, sizeof(cai)); 03139 cai.encmethods = iax2_encryption; 03140 03141 memset(&pds, 0, sizeof(pds)); 03142 tmpstr = ast_strdupa(dest); 03143 parse_dial_string(tmpstr, &pds); 03144 03145 if (!pds.exten) 03146 pds.exten = defaultrdest; 03147 03148 if (create_addr(pds.peer, &sin, &cai)) { 03149 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 03150 return -1; 03151 } 03152 03153 if (!pds.username && !ast_strlen_zero(cai.username)) 03154 pds.username = cai.username; 03155 if (!pds.password && !ast_strlen_zero(cai.secret)) 03156 pds.password = cai.secret; 03157 if (!pds.key && !ast_strlen_zero(cai.outkey)) 03158 pds.key = cai.outkey; 03159 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 03160 pds.context = cai.peercontext; 03161 03162 /* Keep track of the context for outgoing calls too */ 03163 ast_copy_string(c->context, cai.context, sizeof(c->context)); 03164 03165 if (pds.port) 03166 sin.sin_port = htons(atoi(pds.port)); 03167 03168 l = c->cid.cid_num; 03169 n = c->cid.cid_name; 03170 03171 /* Now build request */ 03172 memset(&ied, 0, sizeof(ied)); 03173 03174 /* On new call, first IE MUST be IAX version of caller */ 03175 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 03176 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 03177 if (pds.options && strchr(pds.options, 'a')) { 03178 /* Request auto answer */ 03179 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 03180 } 03181 03182 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 03183 03184 if (l) { 03185 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 03186 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03187 } else { 03188 if (n) 03189 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03190 else 03191 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 03192 } 03193 03194 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton); 03195 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns); 03196 03197 if (n) 03198 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 03199 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani) 03200 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani); 03201 03202 if (!ast_strlen_zero(c->language)) 03203 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 03204 if (!ast_strlen_zero(c->cid.cid_dnid)) 03205 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid); 03206 if (!ast_strlen_zero(c->cid.cid_rdnis)) 03207 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis); 03208 03209 if (pds.context) 03210 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 03211 03212 if (pds.username) 03213 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 03214 03215 if (cai.encmethods) 03216 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 03217 03218 ast_mutex_lock(&iaxsl[callno]); 03219 03220 if (!ast_strlen_zero(c->context)) 03221 ast_string_field_set(iaxs[callno], context, c->context); 03222 03223 if (pds.username) 03224 ast_string_field_set(iaxs[callno], username, pds.username); 03225 03226 iaxs[callno]->encmethods = cai.encmethods; 03227 03228 iaxs[callno]->adsi = cai.adsi; 03229 03230 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 03231 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 03232 03233 if (pds.key) 03234 ast_string_field_set(iaxs[callno], outkey, pds.key); 03235 if (pds.password) 03236 ast_string_field_set(iaxs[callno], secret, pds.password); 03237 03238 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); 03239 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); 03240 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 03241 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 03242 03243 if (iaxs[callno]->maxtime) { 03244 /* Initialize pingtime and auto-congest time */ 03245 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 03246 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 03247 } else if (autokill) { 03248 iaxs[callno]->pingtime = autokill / 2; 03249 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 03250 } 03251 03252 /* send the command using the appropriate socket for this peer */ 03253 iaxs[callno]->sockfd = cai.sockfd; 03254 03255 /* Transmit the string in a "NEW" request */ 03256 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 03257 03258 ast_mutex_unlock(&iaxsl[callno]); 03259 ast_setstate(c, AST_STATE_RINGING); 03260 03261 return 0; 03262 }
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 10310 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_CANEXIST, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
10311 { 10312 int res = 0; 10313 struct iax2_dpcache *dp; 10314 #if 0 10315 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10316 #endif 10317 if ((priority != 1) && (priority != 2)) 10318 return 0; 10319 ast_mutex_lock(&dpcache_lock); 10320 dp = find_cache(chan, data, context, exten, priority); 10321 if (dp) { 10322 if (dp->flags & CACHE_FLAG_CANEXIST) 10323 res= 1; 10324 } 10325 ast_mutex_unlock(&dpcache_lock); 10326 if (!dp) { 10327 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10328 } 10329 return res; 10330 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 3026 of file chan_iax2.c.
References ast_localtime(), ast_strlen_zero(), and t.
Referenced by iax2_call(), and update_registry().
03027 { 03028 time_t t; 03029 struct tm tm; 03030 unsigned int tmp; 03031 time(&t); 03032 if (!ast_strlen_zero(tz)) 03033 ast_localtime(&t, &tm, tz); 03034 else 03035 ast_localtime(&t, &tm, NULL); 03036 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 03037 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 03038 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 03039 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 03040 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 03041 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 03042 return tmp; 03043 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 1977 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), ast_set_flag, ast_string_field_free_memory, ast_variables_destroy(), iax2_registry::callno, chan_iax2_pvt::callno, iax_frame::callno, jb_frame::data, free, iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, iaxq, iaxs, iaxsl, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, lastused, ast_channel::lock, LOG_NOTICE, chan_iax2_pvt::owner, chan_iax2_pvt::reg, iax_frame::retries, update_max_trunk(), and chan_iax2_pvt::vars.
Referenced by __attempt_transmit(), __iax2_poke_noanswer(), __unload_module(), delete_users(), iax2_do_register(), iax2_hangup(), iax2_poke_peer(), peer_destructor(), and socket_process().
01978 { 01979 struct chan_iax2_pvt *pvt; 01980 struct iax_frame *cur; 01981 struct ast_channel *owner; 01982 01983 retry: 01984 pvt = iaxs[callno]; 01985 gettimeofday(&lastused[callno], NULL); 01986 01987 owner = pvt ? pvt->owner : NULL; 01988 01989 if (owner) { 01990 if (ast_mutex_trylock(&owner->lock)) { 01991 ast_log(LOG_NOTICE, "Avoiding IAX destroy deadlock\n"); 01992 ast_mutex_unlock(&iaxsl[callno]); 01993 usleep(1); 01994 ast_mutex_lock(&iaxsl[callno]); 01995 goto retry; 01996 } 01997 } 01998 if (!owner) 01999 iaxs[callno] = NULL; 02000 if (pvt) { 02001 if (!owner) 02002 pvt->owner = NULL; 02003 iax2_destroy_helper(pvt); 02004 02005 /* Already gone */ 02006 ast_set_flag(pvt, IAX_ALREADYGONE); 02007 02008 if (owner) { 02009 /* If there's an owner, prod it to give up */ 02010 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 02011 * because we already hold the owner channel lock. */ 02012 ast_queue_hangup(owner); 02013 } 02014 02015 AST_LIST_LOCK(&iaxq.queue); 02016 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 02017 /* Cancel any pending transmissions */ 02018 if (cur->callno == pvt->callno) 02019 cur->retries = -1; 02020 } 02021 AST_LIST_UNLOCK(&iaxq.queue); 02022 02023 if (pvt->reg) 02024 pvt->reg->callno = 0; 02025 if (!owner) { 02026 jb_frame frame; 02027 if (pvt->vars) { 02028 ast_variables_destroy(pvt->vars); 02029 pvt->vars = NULL; 02030 } 02031 02032 while (jb_getall(pvt->jb, &frame) == JB_OK) 02033 iax2_frame_free(frame.data); 02034 jb_destroy(pvt->jb); 02035 /* gotta free up the stringfields */ 02036 ast_string_field_free_memory(pvt); 02037 free(pvt); 02038 } 02039 } 02040 if (owner) { 02041 ast_mutex_unlock(&owner->lock); 02042 } 02043 if (callno & 0x4000) 02044 update_max_trunk(); 02045 }
static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1914 of file chan_iax2.c.
References ao2_find(), ast_clear_flag, ast_sched_del(), ast_test_flag, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, iax2_user::curauthreq, IAX_MAXAUTHREQ, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, chan_iax2_pvt::pingid, user_unref(), and users.
Referenced by iax2_destroy(), iax2_predestroy(), and stop_stuff().
01915 { 01916 /* Decrement AUTHREQ count if needed */ 01917 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01918 struct iax2_user *user; 01919 struct iax2_user tmp_user = { 01920 .name = pvt->username, 01921 }; 01922 01923 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01924 if (user) { 01925 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01926 user_unref(user); 01927 } 01928 01929 ast_clear_flag(pvt, IAX_MAXAUTHREQ); 01930 } 01931 /* No more pings or lagrq's */ 01932 if (pvt->pingid > -1) 01933 ast_sched_del(sched, pvt->pingid); 01934 pvt->pingid = -1; 01935 if (pvt->lagid > -1) 01936 ast_sched_del(sched, pvt->lagid); 01937 pvt->lagid = -1; 01938 if (pvt->autoid > -1) 01939 ast_sched_del(sched, pvt->autoid); 01940 pvt->autoid = -1; 01941 if (pvt->authid > -1) 01942 ast_sched_del(sched, pvt->authid); 01943 pvt->authid = -1; 01944 if (pvt->initid > -1) 01945 ast_sched_del(sched, pvt->initid); 01946 pvt->initid = -1; 01947 if (pvt->jbid > -1) 01948 ast_sched_del(sched, pvt->jbid); 01949 pvt->jbid = -1; 01950 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 10497 of file chan_iax2.c.
References iax2_peer::addr, AST_DEVICE_INVALID, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_log(), ast_strdupa, ast_strlen_zero(), iax2_peer::defaddr, find_peer(), iax2_peer::historicms, iax2_peer::lastms, LOG_DEBUG, iax2_peer::maxms, option_debug, parse_dial_string(), parsed_dial_string::peer, and peer_unref().
10498 { 10499 struct parsed_dial_string pds; 10500 char *tmp = ast_strdupa(data); 10501 struct iax2_peer *p; 10502 int res = AST_DEVICE_INVALID; 10503 10504 memset(&pds, 0, sizeof(pds)); 10505 parse_dial_string(tmp, &pds); 10506 if (ast_strlen_zero(pds.peer)) 10507 return res; 10508 10509 if (option_debug > 2) 10510 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer); 10511 10512 /* SLD: FIXME: second call to find_peer during registration */ 10513 if (!(p = find_peer(pds.peer, 1))) 10514 return res; 10515 10516 res = AST_DEVICE_UNAVAILABLE; 10517 if (option_debug > 2) 10518 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 10519 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 10520 10521 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 10522 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 10523 /* Peer is registered, or have default IP address 10524 and a valid registration */ 10525 if (p->historicms == 0 || p->historicms <= p->maxms) 10526 /* let the core figure out whether it is in use or not */ 10527 res = AST_DEVICE_UNKNOWN; 10528 } 10529 10530 peer_unref(p); 10531 10532 return res; 10533 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 2653 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02654 { 02655 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 02656 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 2658 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02659 { 02660 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 02661 }
static int iax2_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4788 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04789 { 04790 if (argc < 2 || argc > 3) 04791 return RESULT_SHOWUSAGE; 04792 iaxdebug = 1; 04793 ast_cli(fd, "IAX2 Debugging Enabled\n"); 04794 return RESULT_SUCCESS; 04795 }
static int iax2_do_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4806 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04807 { 04808 if (argc < 3 || argc > 4) 04809 return RESULT_SHOWUSAGE; 04810 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 04811 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 04812 return RESULT_SUCCESS; 04813 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 8471 of file chan_iax2.c.
References iax2_registry::addr, ast_dnsmgr_changed(), ast_dnsmgr_refresh(), AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), iax_ie_data::buf, iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, find_callno(), iax2_destroy(), iax2_do_register_s(), iax2_sched_add(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, iaxsl, LOG_DEBUG, LOG_WARNING, NEW_FORCE, option_debug, iax_ie_data::pos, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, REG_STATE_TIMEOUT, iax2_registry::regstate, send_command(), and iax2_registry::username.
Referenced by __iax2_do_register_s(), load_module(), and reload_config().
08472 { 08473 struct iax_ie_data ied; 08474 if (option_debug && iaxdebug) 08475 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username); 08476 08477 if (reg->dnsmgr && 08478 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) { 08479 /* Maybe the IP has changed, force DNS refresh */ 08480 ast_dnsmgr_refresh(reg->dnsmgr); 08481 } 08482 08483 /* 08484 * if IP has Changed, free allocated call to create a new one with new IP 08485 * call has the pointer to IP and must be updated to the new one 08486 */ 08487 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 08488 ast_mutex_lock(&iaxsl[reg->callno]); 08489 iax2_destroy(reg->callno); 08490 ast_mutex_unlock(&iaxsl[reg->callno]); 08491 reg->callno = 0; 08492 } 08493 if (!reg->addr.sin_addr.s_addr) { 08494 if (option_debug && iaxdebug) 08495 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username); 08496 /* Setup the next registration attempt */ 08497 if (reg->expire > -1) 08498 ast_sched_del(sched, reg->expire); 08499 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08500 return -1; 08501 } 08502 08503 if (!reg->callno) { 08504 if (option_debug) 08505 ast_log(LOG_DEBUG, "Allocate call number\n"); 08506 reg->callno = find_callno(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0); 08507 if (reg->callno < 1) { 08508 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 08509 return -1; 08510 } else if (option_debug) 08511 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno); 08512 iaxs[reg->callno]->reg = reg; 08513 } 08514 /* Schedule the next registration attempt */ 08515 if (reg->expire > -1) 08516 ast_sched_del(sched, reg->expire); 08517 /* Setup the next registration a little early */ 08518 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08519 /* Send the request */ 08520 memset(&ied, 0, sizeof(ied)); 08521 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 08522 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 08523 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 08524 reg->regstate = REG_STATE_REGSENT; 08525 return 0; 08526 }
static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 5595 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
05596 { 05597 #ifdef SCHED_MULTITHREADED 05598 if (schedule_action(__iax2_do_register_s, data)) 05599 #endif 05600 __iax2_do_register_s(data); 05601 return 0; 05602 }
static int iax2_do_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4797 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04798 { 04799 if (argc < 3 || argc > 4) 04800 return RESULT_SHOWUSAGE; 04801 iaxtrunkdebug = 1; 04802 ast_cli(fd, "IAX2 Trunk Debug Requested\n"); 04803 return RESULT_SUCCESS; 04804 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 6288 of file chan_iax2.c.
References AST_FRAME_IAX, ast_sched_del(), auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, iax2_dpcache::exten, iax2_dpcache::flags, iax2_sched_add(), IAX_COMMAND_DPREQ, iax_ie_append_str(), IAX_IE_CALLED_NUMBER, iaxs, iax_ie_data::pos, and send_command().
Referenced by find_cache(), and socket_process().
06289 { 06290 struct iax_ie_data ied; 06291 /* Auto-hangup with 30 seconds of inactivity */ 06292 if (iaxs[callno]->autoid > -1) 06293 ast_sched_del(sched, iaxs[callno]->autoid); 06294 iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno); 06295 memset(&ied, 0, sizeof(ied)); 06296 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 06297 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 06298 dp->flags |= CACHE_FLAG_TRANSMITTED; 06299 }
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 10356 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), CACHE_FLAG_EXISTS, find_cache(), iax2_dpcache::flags, LOG_NOTICE, LOG_WARNING, option_verbose, pbx_builtin_getvar_helper(), pbx_exec(), pbx_findapp(), and VERBOSE_PREFIX_3.
10357 { 10358 char odata[256]; 10359 char req[256]; 10360 char *ncontext; 10361 struct iax2_dpcache *dp; 10362 struct ast_app *dial; 10363 #if 0 10364 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); 10365 #endif 10366 if (priority == 2) { 10367 /* Indicate status, can be overridden in dialplan */ 10368 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 10369 if (dialstatus) { 10370 dial = pbx_findapp(dialstatus); 10371 if (dial) 10372 pbx_exec(chan, dial, ""); 10373 } 10374 return -1; 10375 } else if (priority != 1) 10376 return -1; 10377 ast_mutex_lock(&dpcache_lock); 10378 dp = find_cache(chan, data, context, exten, priority); 10379 if (dp) { 10380 if (dp->flags & CACHE_FLAG_EXISTS) { 10381 ast_copy_string(odata, data, sizeof(odata)); 10382 ncontext = strchr(odata, '/'); 10383 if (ncontext) { 10384 *ncontext = '\0'; 10385 ncontext++; 10386 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 10387 } else { 10388 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 10389 } 10390 if (option_verbose > 2) 10391 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req); 10392 } else { 10393 ast_mutex_unlock(&dpcache_lock); 10394 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 10395 return -1; 10396 } 10397 } 10398 ast_mutex_unlock(&dpcache_lock); 10399 dial = pbx_findapp("Dial"); 10400 if (dial) { 10401 return pbx_exec(chan, dial, req); 10402 } else { 10403 ast_log(LOG_WARNING, "No dial application registered\n"); 10404 } 10405 return -1; 10406 }
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 10287 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_EXISTS, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
10288 { 10289 struct iax2_dpcache *dp; 10290 int res = 0; 10291 #if 0 10292 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10293 #endif 10294 if ((priority != 1) && (priority != 2)) 10295 return 0; 10296 ast_mutex_lock(&dpcache_lock); 10297 dp = find_cache(chan, data, context, exten, priority); 10298 if (dp) { 10299 if (dp->flags & CACHE_FLAG_EXISTS) 10300 res= 1; 10301 } 10302 ast_mutex_unlock(&dpcache_lock); 10303 if (!dp) { 10304 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10305 } 10306 return res; 10307 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 2680 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.
02681 { 02682 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 02683 ast_mutex_lock(&iaxsl[callno]); 02684 if (iaxs[callno]) 02685 iaxs[callno]->owner = newchan; 02686 else 02687 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 02688 ast_mutex_unlock(&iaxsl[callno]); 02689 return 0; 02690 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1443 of file chan_iax2.c.
References ast_sched_del(), iax_frame_free(), and iax_frame::retrans.
Referenced by __attempt_transmit(), __do_deliver(), __get_from_jb(), complete_transfer(), iax2_destroy(), and schedule_delivery().
01444 { 01445 if (fr->retrans > -1) 01446 ast_sched_del(sched, fr->retrans); 01447 iax_frame_free(fr); 01448 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len | |||
) | [static] |
Definition at line 1157 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), peer_unref(), peers, and realtime_peer().
Referenced by find_callno().
01158 { 01159 struct iax2_peer *peer = NULL; 01160 int res = 0; 01161 struct ao2_iterator i; 01162 01163 i = ao2_iterator_init(peers, 0); 01164 while ((peer = ao2_iterator_next(&i))) { 01165 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01166 (peer->addr.sin_port == sin.sin_port)) { 01167 ast_copy_string(host, peer->name, len); 01168 peer_unref(peer); 01169 res = 1; 01170 break; 01171 } 01172 peer_unref(peer); 01173 } 01174 01175 if (!peer) { 01176 peer = realtime_peer(NULL, &sin); 01177 if (peer) { 01178 ast_copy_string(host, peer->name, len); 01179 peer_unref(peer); 01180 res = 1; 01181 } 01182 } 01183 01184 return res; 01185 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 3587 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), ast_test_flag, IAX_TRUNK, peer_unref(), and peers.
Referenced by check_access().
03588 { 03589 struct iax2_peer *peer; 03590 int res = 0; 03591 struct ao2_iterator i; 03592 03593 i = ao2_iterator_init(peers, 0); 03594 while ((peer = ao2_iterator_next(&i))) { 03595 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 03596 (peer->addr.sin_port == sin.sin_port)) { 03597 res = ast_test_flag(peer, IAX_TRUNK); 03598 peer_unref(peer); 03599 break; 03600 } 03601 peer_unref(peer); 03602 } 03603 03604 return res; 03605 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3264 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_verbose(), iax_ie_data::buf, iax2_registry::callno, error(), ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, iaxs, iaxsl, LOG_DEBUG, option_debug, option_verbose, iax_ie_data::pos, PTR_TO_CALLNO, send_command_final(), ast_channel::tech_pvt, and VERBOSE_PREFIX_3.
03265 { 03266 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03267 int alreadygone; 03268 struct iax_ie_data ied; 03269 memset(&ied, 0, sizeof(ied)); 03270 ast_mutex_lock(&iaxsl[callno]); 03271 if (callno && iaxs[callno]) { 03272 if (option_debug) 03273 ast_log(LOG_DEBUG, "We're hanging up %s with cause %i now...\n", c->name, c->hangupcause); 03274 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 03275 /* Send the hangup unless we have had a transmission error or are already gone */ 03276 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 03277 if (!iaxs[callno]->error && !alreadygone) { 03278 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 03279 if (!iaxs[callno]) { 03280 ast_mutex_unlock(&iaxsl[callno]); 03281 return 0; 03282 } 03283 } 03284 /* Explicitly predestroy it */ 03285 iax2_predestroy(callno); 03286 /* If we were already gone to begin with, destroy us now */ 03287 if (alreadygone && iaxs[callno]) { 03288 if (option_debug) 03289 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name); 03290 iax2_destroy(callno); 03291 } 03292 } 03293 ast_mutex_unlock(&iaxsl[callno]); 03294 if (option_verbose > 2) 03295 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name); 03296 return 0; 03297 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 3533 of file chan_iax2.c.
References AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_FRAME_CONTROL, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iaxs, iaxsl, LOG_DEBUG, option_debug, PTR_TO_CALLNO, send_command(), and ast_channel::tech_pvt.
03534 { 03535 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03536 struct chan_iax2_pvt *pvt; 03537 int res = 0; 03538 03539 if (option_debug && iaxdebug) 03540 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition); 03541 03542 ast_mutex_lock(&iaxsl[callno]); 03543 pvt = iaxs[callno]; 03544 03545 switch (condition) { 03546 case AST_CONTROL_HOLD: 03547 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03548 ast_moh_start(c, data, pvt->mohinterpret); 03549 goto done; 03550 } 03551 break; 03552 case AST_CONTROL_UNHOLD: 03553 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03554 ast_moh_stop(c); 03555 goto done; 03556 } 03557 } 03558 03559 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 03560 03561 done: 03562 ast_mutex_unlock(&iaxsl[callno]); 03563 03564 return res; 03565 }
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 10333 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_MATCHMORE, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
10334 { 10335 int res = 0; 10336 struct iax2_dpcache *dp; 10337 #if 0 10338 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10339 #endif 10340 if ((priority != 1) && (priority != 2)) 10341 return 0; 10342 ast_mutex_lock(&dpcache_lock); 10343 dp = find_cache(chan, data, context, exten, priority); 10344 if (dp) { 10345 if (dp->flags & CACHE_FLAG_MATCHMORE) 10346 res= 1; 10347 } 10348 ast_mutex_unlock(&dpcache_lock); 10349 if (!dp) { 10350 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10351 } 10352 return res; 10353 }
static int iax2_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4815 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04816 { 04817 if (argc < 3 || argc > 4) 04818 return RESULT_SHOWUSAGE; 04819 iaxdebug = 0; 04820 ast_cli(fd, "IAX2 Debugging Disabled\n"); 04821 return RESULT_SUCCESS; 04822 }
static int iax2_no_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4833 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04834 { 04835 if (argc < 4 || argc > 5) 04836 return RESULT_SHOWUSAGE; 04837 jb_setoutput(jb_error_output, jb_warning_output, NULL); 04838 jb_debug_output("\n"); 04839 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 04840 return RESULT_SUCCESS; 04841 }
static int iax2_no_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4824 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04825 { 04826 if (argc < 4 || argc > 5) 04827 return RESULT_SHOWUSAGE; 04828 iaxtrunkdebug = 0; 04829 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n"); 04830 return RESULT_SUCCESS; 04831 }
static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 8670 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
08671 { 08672 struct iax2_peer *peer = (struct iax2_peer *)data; 08673 peer->pokeexpire = -1; 08674 #ifdef SCHED_MULTITHREADED 08675 if (schedule_action(__iax2_poke_noanswer, data)) 08676 #endif 08677 __iax2_poke_noanswer(data); 08678 peer_unref(peer); 08679 return 0; 08680 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 8691 of file chan_iax2.c.
References iax2_peer::addr, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), iax2_peer::callno, DEFAULT_MAXMS, iax2_peer::dnsmgr, find_callno(), iax2_peer::historicms, iax2_destroy(), iax2_poke_noanswer(), iax2_sched_add(), IAX_COMMAND_POKE, iaxs, iaxsl, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, iax2_peer::maxms, NEW_FORCE, peer_ref(), peer_unref(), chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, send_command(), and iax2_peer::sockfd.
Referenced by __iax2_poke_peer_s(), iax2_poke_peer_cb(), poke_all_peers(), reg_source_db(), and update_registry().
08692 { 08693 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) { 08694 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 08695 immediately after clearing things out */ 08696 peer->lastms = 0; 08697 peer->historicms = 0; 08698 peer->pokeexpire = -1; 08699 peer->callno = 0; 08700 return 0; 08701 } 08702 if (peer->callno > 0) { 08703 ast_log(LOG_NOTICE, "Still have a callno...\n"); 08704 ast_mutex_lock(&iaxsl[peer->callno]); 08705 iax2_destroy(peer->callno); 08706 ast_mutex_unlock(&iaxsl[peer->callno]); 08707 } 08708 if (heldcall) 08709 ast_mutex_unlock(&iaxsl[heldcall]); 08710 peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0); 08711 if (heldcall) 08712 ast_mutex_lock(&iaxsl[heldcall]); 08713 if (peer->callno < 1) { 08714 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 08715 return -1; 08716 } 08717 08718 /* Speed up retransmission times for this qualify call */ 08719 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 08720 iaxs[peer->callno]->peerpoke = peer; 08721 08722 /* Remove any pending pokeexpire task */ 08723 if (peer->pokeexpire > -1) { 08724 if (!ast_sched_del(sched, peer->pokeexpire)) { 08725 peer->pokeexpire = -1; 08726 peer_unref(peer); 08727 } 08728 } 08729 08730 /* Queue up a new task to handle no reply */ 08731 /* If the host is already unreachable then use the unreachable interval instead */ 08732 if (peer->lastms < 0) { 08733 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 08734 } else 08735 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 08736 08737 if (peer->pokeexpire == -1) 08738 peer_unref(peer); 08739 08740 /* And send the poke */ 08741 send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1); 08742 08743 return 0; 08744 }
static int iax2_poke_peer_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 8682 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
08683 { 08684 struct iax2_peer *peer = obj; 08685 08686 iax2_poke_peer(peer, 0); 08687 08688 return 0; 08689 }
static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 6329 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
06330 { 06331 struct iax2_peer *peer = (struct iax2_peer *)data; 06332 peer->pokeexpire = -1; 06333 #ifdef SCHED_MULTITHREADED 06334 if (schedule_action(__iax2_poke_peer_s, data)) 06335 #endif 06336 __iax2_poke_peer_s(data); 06337 return 0; 06338 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 1956 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().
01957 { 01958 struct ast_channel *c; 01959 struct chan_iax2_pvt *pvt = iaxs[callno]; 01960 01961 if (!pvt) 01962 return -1; 01963 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 01964 iax2_destroy_helper(pvt); 01965 ast_set_flag(pvt, IAX_ALREADYGONE); 01966 } 01967 c = pvt->owner; 01968 if (c) { 01969 c->tech_pvt = NULL; 01970 iax2_queue_hangup(callno); 01971 pvt->owner = NULL; 01972 ast_module_unref(ast_module_info->self); 01973 } 01974 return 0; 01975 }
static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 8346 of file chan_iax2.c.
References ast_cond_timedwait(), ast_cond_wait(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_tvadd(), handle_deferred_full_frames(), iax2_process_thread_cleanup(), IAX_IOSTATE_IDLE, IAX_IOSTATE_PROCESSING, IAX_IOSTATE_READY, IAX_IOSTATE_SCHEDREADY, IAX_TYPE_DYNAMIC, iaxactivethreadcount, iaxdynamicthreadcount, insert_idle_thread(), socket_process(), t, and thread.
Referenced by find_idle_thread(), and start_network_thread().
08347 { 08348 struct iax2_thread *thread = data; 08349 struct timeval tv; 08350 struct timespec ts; 08351 int put_into_idle = 0; 08352 08353 ast_atomic_fetchadd_int(&iaxactivethreadcount,1); 08354 pthread_cleanup_push(iax2_process_thread_cleanup, data); 08355 for(;;) { 08356 /* Wait for something to signal us to be awake */ 08357 ast_mutex_lock(&thread->lock); 08358 08359 /* Flag that we're ready to accept signals */ 08360 thread->ready_for_signal = 1; 08361 08362 /* Put into idle list if applicable */ 08363 if (put_into_idle) 08364 insert_idle_thread(thread); 08365 08366 if (thread->type == IAX_TYPE_DYNAMIC) { 08367 struct iax2_thread *t = NULL; 08368 /* Wait to be signalled or time out */ 08369 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08370 ts.tv_sec = tv.tv_sec; 08371 ts.tv_nsec = tv.tv_usec * 1000; 08372 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 08373 /* This thread was never put back into the available dynamic 08374 * thread list, so just go away. */ 08375 if (!put_into_idle) { 08376 ast_mutex_unlock(&thread->lock); 08377 break; 08378 } 08379 AST_LIST_LOCK(&dynamic_list); 08380 /* Account for the case where this thread is acquired *right* after a timeout */ 08381 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 08382 iaxdynamicthreadcount--; 08383 AST_LIST_UNLOCK(&dynamic_list); 08384 if (t) { 08385 /* This dynamic thread timed out waiting for a task and was 08386 * not acquired immediately after the timeout, 08387 * so it's time to go away. */ 08388 ast_mutex_unlock(&thread->lock); 08389 break; 08390 } 08391 /* Someone grabbed our thread *right* after we timed out. 08392 * Wait for them to set us up with something to do and signal 08393 * us to continue. */ 08394 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08395 ts.tv_sec = tv.tv_sec; 08396 ts.tv_nsec = tv.tv_usec * 1000; 08397 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) 08398 { 08399 ast_mutex_unlock(&thread->lock); 08400 break; 08401 } 08402 } 08403 } else { 08404 ast_cond_wait(&thread->cond, &thread->lock); 08405 } 08406 08407 /* Go back into our respective list */ 08408 put_into_idle = 1; 08409 08410 ast_mutex_unlock(&thread->lock); 08411 08412 if (thread->iostate == IAX_IOSTATE_IDLE) 08413 continue; 08414 08415 /* Add ourselves to the active list now */ 08416 AST_LIST_LOCK(&active_list); 08417 AST_LIST_INSERT_HEAD(&active_list, thread, list); 08418 AST_LIST_UNLOCK(&active_list); 08419 08420 /* See what we need to do */ 08421 switch(thread->iostate) { 08422 case IAX_IOSTATE_READY: 08423 thread->actions++; 08424 thread->iostate = IAX_IOSTATE_PROCESSING; 08425 socket_process(thread); 08426 handle_deferred_full_frames(thread); 08427 break; 08428 case IAX_IOSTATE_SCHEDREADY: 08429 thread->actions++; 08430 thread->iostate = IAX_IOSTATE_PROCESSING; 08431 #ifdef SCHED_MULTITHREADED 08432 thread->schedfunc(thread->scheddata); 08433 #endif 08434 break; 08435 } 08436 time(&thread->checktime); 08437 thread->iostate = IAX_IOSTATE_IDLE; 08438 #ifdef DEBUG_SCHED_MULTITHREAD 08439 thread->curfunc[0]='\0'; 08440 #endif 08441 08442 /* Now... remove ourselves from the active list, and return to the idle list */ 08443 AST_LIST_LOCK(&active_list); 08444 AST_LIST_REMOVE(&active_list, thread, list); 08445 AST_LIST_UNLOCK(&active_list); 08446 08447 /* Make sure another frame didn't sneak in there after we thought we were done. */ 08448 handle_deferred_full_frames(thread); 08449 } 08450 08451 /*!\note For some reason, idle threads are exiting without being removed 08452 * from an idle list, which is causing memory corruption. Forcibly remove 08453 * it from the list, if it's there. 08454 */ 08455 AST_LIST_LOCK(&idle_list); 08456 AST_LIST_REMOVE(&idle_list, thread, list); 08457 AST_LIST_UNLOCK(&idle_list); 08458 08459 AST_LIST_LOCK(&dynamic_list); 08460 AST_LIST_REMOVE(&dynamic_list, thread, list); 08461 AST_LIST_UNLOCK(&dynamic_list); 08462 08463 /* I am exiting here on my own volition, I need to clean up my own data structures 08464 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 08465 */ 08466 pthread_cleanup_pop(1); 08467 08468 return NULL; 08469 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 8337 of file chan_iax2.c.
References ast_cond_destroy(), ast_mutex_destroy(), free, iaxactivethreadcount, and thread.
Referenced by iax2_process_thread().
08338 { 08339 struct iax2_thread *thread = data; 08340 ast_mutex_destroy(&thread->lock); 08341 ast_cond_destroy(&thread->cond); 08342 free(thread); 08343 ast_atomic_dec_and_test(&iaxactivethreadcount); 08344 }
static int iax2_prov_cmd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 8627 of file chan_iax2.c.
References ast_cli(), iax2_provision(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
08628 { 08629 int force = 0; 08630 int res; 08631 if (argc < 4) 08632 return RESULT_SHOWUSAGE; 08633 if ((argc > 4)) { 08634 if (!strcasecmp(argv[4], "forced")) 08635 force = 1; 08636 else 08637 return RESULT_SHOWUSAGE; 08638 } 08639 res = iax2_provision(NULL, -1, argv[2], argv[3], force); 08640 if (res < 0) 08641 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]); 08642 else if (res < 1) 08643 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]); 08644 else 08645 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : ""); 08646 return RESULT_SUCCESS; 08647 }
static char* iax2_prov_complete_template_3rd | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 8528 of file chan_iax2.c.
References iax_prov_complete_template().
08529 { 08530 if (pos != 3) 08531 return NULL; 08532 return iax_prov_complete_template(line, word, pos, state); 08533 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 8535 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_set_flag, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, iax2_registry::callno, create_addr(), find_callno(), iax2_sched_add(), IAX_COMMAND_PROVISION, iax_ie_append_raw(), IAX_IE_PROVISIONING, IAX_PROVISION, iax_provision_build(), iaxs, iaxsl, LOG_DEBUG, NEW_FORCE, option_debug, iax_ie_data::pos, send_command(), and create_addr_info::sockfd.
Referenced by check_provisioning(), iax2_prov_app(), and iax2_prov_cmd().
08536 { 08537 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 08538 is found for template */ 08539 struct iax_ie_data provdata; 08540 struct iax_ie_data ied; 08541 unsigned int sig; 08542 struct sockaddr_in sin; 08543 int callno; 08544 struct create_addr_info cai; 08545 08546 memset(&cai, 0, sizeof(cai)); 08547 08548 if (option_debug) 08549 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template); 08550 08551 if (iax_provision_build(&provdata, &sig, template, force)) { 08552 if (option_debug) 08553 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template); 08554 return 0; 08555 } 08556 08557 if (end) { 08558 memcpy(&sin, end, sizeof(sin)); 08559 cai.sockfd = sockfd; 08560 } else if (create_addr(dest, &sin, &cai)) 08561 return -1; 08562 08563 /* Build the rest of the message */ 08564 memset(&ied, 0, sizeof(ied)); 08565 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 08566 08567 callno = find_callno(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 08568 if (!callno) 08569 return -1; 08570 08571 ast_mutex_lock(&iaxsl[callno]); 08572 if (iaxs[callno]) { 08573 /* Schedule autodestruct in case they don't ever give us anything back */ 08574 if (iaxs[callno]->autoid > -1) 08575 ast_sched_del(sched, iaxs[callno]->autoid); 08576 iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno); 08577 ast_set_flag(iaxs[callno], IAX_PROVISION); 08578 /* Got a call number now, so go ahead and send the provisioning information */ 08579 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 08580 } 08581 ast_mutex_unlock(&iaxsl[callno]); 08582 08583 return 1; 08584 }
static int iax2_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2150 of file chan_iax2.c.
References ast_cli(), ast_set_flag, ast_test_flag, expire_registry(), find_peer(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, peer_ref(), peer_unref(), reload_config(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02151 { 02152 struct iax2_peer *peer; 02153 02154 if (argc != 4) 02155 return RESULT_SHOWUSAGE; 02156 if (!strcmp(argv[3],"all")) { 02157 reload_config(); 02158 ast_cli(fd, "OK cache is flushed.\n"); 02159 } else if ((peer = find_peer(argv[3], 0))) { 02160 if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 02161 ast_set_flag(peer, IAX_RTAUTOCLEAR); 02162 expire_registry(peer_ref(peer)); 02163 ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]); 02164 } else { 02165 ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]); 02166 } 02167 peer_unref(peer); 02168 } else { 02169 ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]); 02170 } 02171 02172 return RESULT_SUCCESS; 02173 }
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 1526 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_control_data(), iaxs, and iaxsl.
Referenced by socket_process().
01528 { 01529 for (;;) { 01530 if (iaxs[callno] && iaxs[callno]->owner) { 01531 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01532 /* Avoid deadlock by pausing and trying again */ 01533 ast_mutex_unlock(&iaxsl[callno]); 01534 usleep(1); 01535 ast_mutex_lock(&iaxsl[callno]); 01536 } else { 01537 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 01538 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01539 break; 01540 } 01541 } else 01542 break; 01543 } 01544 return 0; 01545 }
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 1460 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), iaxs, and iaxsl.
Referenced by __attempt_transmit(), __auto_congest(), __do_deliver(), and __get_from_jb().
01461 { 01462 for (;;) { 01463 if (iaxs[callno] && iaxs[callno]->owner) { 01464 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01465 /* Avoid deadlock by pausing and trying again */ 01466 ast_mutex_unlock(&iaxsl[callno]); 01467 usleep(1); 01468 ast_mutex_lock(&iaxsl[callno]); 01469 } else { 01470 ast_queue_frame(iaxs[callno]->owner, f); 01471 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01472 break; 01473 } 01474 } else 01475 break; 01476 } 01477 return 0; 01478 }
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 1493 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), iaxs, and iaxsl.
Referenced by iax2_predestroy().
01494 { 01495 for (;;) { 01496 if (iaxs[callno] && iaxs[callno]->owner) { 01497 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01498 /* Avoid deadlock by pausing and trying again */ 01499 ast_mutex_unlock(&iaxsl[callno]); 01500 usleep(1); 01501 ast_mutex_lock(&iaxsl[callno]); 01502 } else { 01503 ast_queue_hangup(iaxs[callno]->owner); 01504 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01505 break; 01506 } 01507 } else 01508 break; 01509 } 01510 return 0; 01511 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static, read] |
Definition at line 3325 of file chan_iax2.c.
References ast_log(), ast_null_frame, LOG_NOTICE, and option_verbose.
03326 { 03327 if (option_verbose > 3) 03328 ast_log(LOG_NOTICE, "I should never be called!\n"); 03329 return &ast_null_frame; 03330 }
static int iax2_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 5803 of file chan_iax2.c.
References iax2_registry::addr, ast_calloc, ast_dnsmgr_lookup(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), copy(), iax2_registry::dnsmgr, iax2_registry::expire, free, hostname, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, LOG_WARNING, iax2_registry::refresh, iax2_registry::secret, strsep(), and iax2_registry::username.
Referenced by set_config().
05804 { 05805 struct iax2_registry *reg; 05806 char copy[256]; 05807 char *username, *hostname, *secret; 05808 char *porta; 05809 char *stringp=NULL; 05810 05811 if (!value) 05812 return -1; 05813 ast_copy_string(copy, value, sizeof(copy)); 05814 stringp=copy; 05815 username = strsep(&stringp, "@"); 05816 hostname = strsep(&stringp, "@"); 05817 if (!hostname) { 05818 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 05819 return -1; 05820 } 05821 stringp=username; 05822 username = strsep(&stringp, ":"); 05823 secret = strsep(&stringp, ":"); 05824 stringp=hostname; 05825 hostname = strsep(&stringp, ":"); 05826 porta = strsep(&stringp, ":"); 05827 05828 if (porta && !atoi(porta)) { 05829 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 05830 return -1; 05831 } 05832 if (!(reg = ast_calloc(1, sizeof(*reg)))) 05833 return -1; 05834 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) { 05835 free(reg); 05836 return -1; 05837 } 05838 ast_copy_string(reg->username, username, sizeof(reg->username)); 05839 if (secret) 05840 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 05841 reg->expire = -1; 05842 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 05843 reg->addr.sin_family = AF_INET; 05844 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 05845 AST_LIST_LOCK(®istrations); 05846 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 05847 AST_LIST_UNLOCK(®istrations); 05848 05849 return 0; 05850 }
static int iax2_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 10060 of file chan_iax2.c.
References reload_config().
10061 { 10062 return reload_config(); 10063 }
static struct ast_channel * iax2_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static, read] |
Definition at line 8756 of file chan_iax2.c.
References ast_best_codec(), AST_CAUSE_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_flags, ast_getformatname(), ast_hangup(), ast_iax2_new(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DOWN, ast_strdupa, ast_string_field_set, ast_test_flag, ast_translator_best_choice(), iax2_registry::callno, create_addr_info::capability, create_addr(), find_callno(), fmt, create_addr_info::found, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, iaxsl, LOG_WARNING, make_trunk(), create_addr_info::maxtime, chan_iax2_pvt::maxtime, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), parsed_dial_string::peer, parsed_dial_string::port, ast_channel::readformat, create_addr_info::sockfd, and ast_channel::writeformat.
08757 { 08758 int callno; 08759 int res; 08760 int fmt, native; 08761 struct sockaddr_in sin; 08762 struct ast_channel *c; 08763 struct parsed_dial_string pds; 08764 struct create_addr_info cai; 08765 char *tmpstr; 08766 08767 memset(&pds, 0, sizeof(pds)); 08768 tmpstr = ast_strdupa(data); 08769 parse_dial_string(tmpstr, &pds); 08770 08771 memset(&cai, 0, sizeof(cai)); 08772 cai.capability = iax2_capability; 08773 08774 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08775 08776 if (!pds.peer) { 08777 ast_log(LOG_WARNING, "No peer given\n"); 08778 return NULL; 08779 } 08780 08781 08782 /* Populate our address from the given */ 08783 if (create_addr(pds.peer, &sin, &cai)) { 08784 *cause = AST_CAUSE_UNREGISTERED; 08785 return NULL; 08786 } 08787 08788 if (pds.port) 08789 sin.sin_port = htons(atoi(pds.port)); 08790 08791 callno = find_callno(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 08792 if (callno < 1) { 08793 ast_log(LOG_WARNING, "Unable to create call\n"); 08794 *cause = AST_CAUSE_CONGESTION; 08795 return NULL; 08796 } 08797 08798 ast_mutex_lock(&iaxsl[callno]); 08799 08800 /* If this is a trunk, update it now */ 08801 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08802 if (ast_test_flag(&cai, IAX_TRUNK)) { 08803 int new_callno; 08804 if ((new_callno = make_trunk(callno, 1)) != -1) 08805 callno = new_callno; 08806 } 08807 iaxs[callno]->maxtime = cai.maxtime; 08808 if (cai.found) 08809 ast_string_field_set(iaxs[callno], host, pds.peer); 08810 08811 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 08812 08813 ast_mutex_unlock(&iaxsl[callno]); 08814 08815 if (c) { 08816 /* Choose a format we can live with */ 08817 if (c->nativeformats & format) 08818 c->nativeformats &= format; 08819 else { 08820 native = c->nativeformats; 08821 fmt = format; 08822 res = ast_translator_best_choice(&fmt, &native); 08823 if (res < 0) { 08824 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 08825 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 08826 ast_hangup(c); 08827 return NULL; 08828 } 08829 c->nativeformats = native; 08830 } 08831 c->readformat = ast_best_codec(c->nativeformats); 08832 c->writeformat = c->readformat; 08833 } 08834 08835 return c; 08836 }
static int iax2_sched_add | ( | struct sched_context * | con, | |
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 972 of file chan_iax2.c.
References ast_sched_add(), and signal_condition().
Referenced by __attempt_transmit(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), auth_fail(), find_callno(), iax2_ack_registry(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_poke_peer(), iax2_provision(), make_trunk(), network_thread(), realtime_peer(), reg_source_db(), socket_process(), update_jbsched(), and update_registry().
00973 { 00974 int res; 00975 00976 res = ast_sched_add(con, when, callback, data); 00977 signal_condition(&sched_lock, &sched_cond); 00978 00979 return res; 00980 }
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 4137 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, iax_frame::afdatalen, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_test_flag, calc_timestamp(), ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, chan_iax2_pvt::callno, iax_frame::callno, compress_subclass(), ast_iax2_full_hdr::csub, iax_frame::data, ast_frame::data, iax_frame::datalen, ast_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, chan_iax2_pvt::ecx, encrypt_frame(), iax_frame::final, ast_frame::frametype, iax2_transmit(), iax2_trunk_queue(), IAX_COMMAND_ACK, IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_showframe(), IAX_TRUNK, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, chan_iax2_pvt::lastsent, LOG_WARNING, MAX_RETRY_TIME, MIN_RETRY_TIME, ast_iax2_full_hdr::oseqno, chan_iax2_pvt::oseqno, iax_frame::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, iax_frame::retries, iax_frame::retrytime, ast_iax2_full_hdr::scallno, chan_iax2_pvt::semirand, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, iax_frame::transfer, TRANSFER_MEDIAPASS, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, ast_iax2_mini_hdr::ts, ast_iax2_video_hdr::ts, ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_full_hdr::type, and ast_iax2_video_hdr::zeros.
Referenced by __send_command(), iax2_write(), and socket_process().
04138 { 04139 /* Queue a packet for delivery on a given private structure. Use "ts" for 04140 timestamp, or calculate if ts is 0. Send immediately without retransmission 04141 or delayed, with retransmission */ 04142 struct ast_iax2_full_hdr *fh; 04143 struct ast_iax2_mini_hdr *mh; 04144 struct ast_iax2_video_hdr *vh; 04145 struct { 04146 struct iax_frame fr2; 04147 unsigned char buffer[4096]; 04148 } frb; 04149 struct iax_frame *fr; 04150 int res; 04151 int sendmini=0; 04152 unsigned int lastsent; 04153 unsigned int fts; 04154 04155 frb.fr2.afdatalen = sizeof(frb.buffer); 04156 04157 if (!pvt) { 04158 ast_log(LOG_WARNING, "No private structure for packet?\n"); 04159 return -1; 04160 } 04161 04162 lastsent = pvt->lastsent; 04163 04164 /* Calculate actual timestamp */ 04165 fts = calc_timestamp(pvt, ts, f); 04166 04167 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 04168 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 04169 * increment the "predicted timestamps" for voice, if we're predecting */ 04170 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 04171 return 0; 04172 04173 04174 if ((ast_test_flag(pvt, IAX_TRUNK) || 04175 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 04176 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 04177 /* High two bytes are the same on timestamp, or sending on a trunk */ && 04178 (f->frametype == AST_FRAME_VOICE) 04179 /* is a voice frame */ && 04180 (f->subclass == pvt->svoiceformat) 04181 /* is the same type */ ) { 04182 /* Force immediate rather than delayed transmission */ 04183 now = 1; 04184 /* Mark that mini-style frame is appropriate */ 04185 sendmini = 1; 04186 } 04187 if (((fts & 0xFFFF8000L) == (lastsent & 0xFFFF8000L)) && 04188 (f->frametype == AST_FRAME_VIDEO) && 04189 ((f->subclass & ~0x1) == pvt->svideoformat)) { 04190 now = 1; 04191 sendmini = 1; 04192 } 04193 /* Allocate an iax_frame */ 04194 if (now) { 04195 fr = &frb.fr2; 04196 } else 04197 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)); 04198 if (!fr) { 04199 ast_log(LOG_WARNING, "Out of memory\n"); 04200 return -1; 04201 } 04202 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 04203 iax_frame_wrap(fr, f); 04204 04205 fr->ts = fts; 04206 fr->callno = pvt->callno; 04207 fr->transfer = transfer; 04208 fr->final = final; 04209 if (!sendmini) { 04210 /* We need a full frame */ 04211 if (seqno > -1) 04212 fr->oseqno = seqno; 04213 else 04214 fr->oseqno = pvt->oseqno++; 04215 fr->iseqno = pvt->iseqno; 04216 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr)); 04217 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 04218 fh->ts = htonl(fr->ts); 04219 fh->oseqno = fr->oseqno; 04220 if (transfer) { 04221 fh->iseqno = 0; 04222 } else 04223 fh->iseqno = fr->iseqno; 04224 /* Keep track of the last thing we've acknowledged */ 04225 if (!transfer) 04226 pvt->aseqno = fr->iseqno; 04227 fh->type = fr->af.frametype & 0xFF; 04228 if (fr->af.frametype == AST_FRAME_VIDEO) 04229 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 04230 else 04231 fh->csub = compress_subclass(fr->af.subclass); 04232 if (transfer) { 04233 fr->dcallno = pvt->transfercallno; 04234 } else 04235 fr->dcallno = pvt->peercallno; 04236 fh->dcallno = htons(fr->dcallno); 04237 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 04238 fr->data = fh; 04239 fr->retries = 0; 04240 /* Retry after 2x the ping time has passed */ 04241 fr->retrytime = pvt->pingtime * 2; 04242 if (fr->retrytime < MIN_RETRY_TIME) 04243 fr->retrytime = MIN_RETRY_TIME; 04244 if (fr->retrytime > MAX_RETRY_TIME) 04245 fr->retrytime = MAX_RETRY_TIME; 04246 /* Acks' don't get retried */ 04247 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 04248 fr->retries = -1; 04249 else if (f->frametype == AST_FRAME_VOICE) 04250 pvt->svoiceformat = f->subclass; 04251 else if (f->frametype == AST_FRAME_VIDEO) 04252 pvt->svideoformat = f->subclass & ~0x1; 04253 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04254 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04255 if (iaxdebug) { 04256 if (fr->transfer) 04257 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04258 else 04259 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04260 } 04261 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 04262 } else 04263 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04264 } 04265 04266 if (now) { 04267 res = send_packet(fr); 04268 } else 04269 res = iax2_transmit(fr); 04270 } else { 04271 if (ast_test_flag(pvt, IAX_TRUNK)) { 04272 iax2_trunk_queue(pvt, fr); 04273 res = 0; 04274 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 04275 /* Video frame have no sequence number */ 04276 fr->oseqno = -1; 04277 fr->iseqno = -1; 04278 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr)); 04279 vh->zeros = 0; 04280 vh->callno = htons(0x8000 | fr->callno); 04281 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 04282 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 04283 fr->data = vh; 04284 fr->retries = -1; 04285 res = send_packet(fr); 04286 } else { 04287 /* Mini-frames have no sequence number */ 04288 fr->oseqno = -1; 04289 fr->iseqno = -1; 04290 /* Mini frame will do */ 04291 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr)); 04292 mh->callno = htons(fr->callno); 04293 mh->ts = htons(fr->ts & 0xFFFF); 04294 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 04295 fr->data = mh; 04296 fr->retries = -1; 04297 if (pvt->transferring == TRANSFER_MEDIAPASS) 04298 fr->transfer = 1; 04299 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04300 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04301 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 04302 } else 04303 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04304 } 04305 res = send_packet(fr); 04306 } 04307 } 04308 return res; 04309 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 2675 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02676 { 02677 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 02678 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 2670 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.
02671 { 02672 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1); 02673 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | dest, | |||
const char * | text, | |||
int | ispdu | |||
) | [static] |
Definition at line 2663 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02664 { 02665 02666 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 02667 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 02668 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 3299 of file chan_iax2.c.
References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_malloc, AST_OPTION_FLAG_REQUEST, AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, ast_option_header::data, errno, ast_option_header::flag, free, ast_option_header::option, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03300 { 03301 struct ast_option_header *h; 03302 int res; 03303 03304 switch (option) { 03305 case AST_OPTION_TXGAIN: 03306 case AST_OPTION_RXGAIN: 03307 /* these two cannot be sent, because they require a result */ 03308 errno = ENOSYS; 03309 return -1; 03310 default: 03311 if (!(h = ast_malloc(datalen + sizeof(*h)))) 03312 return -1; 03313 03314 h->flag = AST_OPTION_FLAG_REQUEST; 03315 h->option = htons(option); 03316 memcpy(h->data, data, datalen); 03317 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 03318 AST_CONTROL_OPTION, 0, (unsigned char *) h, 03319 datalen + sizeof(*h), -1); 03320 free(h); 03321 return res; 03322 } 03323 }
static int iax2_show_cache | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2354 of file chan_iax2.c.
References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, CACHE_FLAG_TRANSMITTED, CACHE_FLAG_UNKNOWN, dpcache, iax2_dpcache::expiry, iax2_dpcache::exten, iax2_dpcache::flags, iax2_dpcache::next, iax2_dpcache::peercontext, RESULT_SUCCESS, s, and iax2_dpcache::waiters.
02355 { 02356 struct iax2_dpcache *dp; 02357 char tmp[1024], *pc; 02358 int s; 02359 int x,y; 02360 struct timeval tv; 02361 gettimeofday(&tv, NULL); 02362 ast_mutex_lock(&dpcache_lock); 02363 dp = dpcache; 02364 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 02365 while(dp) { 02366 s = dp->expiry.tv_sec - tv.tv_sec; 02367 tmp[0] = '\0'; 02368 if (dp->flags & CACHE_FLAG_EXISTS) 02369 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 02370 if (dp->flags & CACHE_FLAG_NONEXISTENT) 02371 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 02372 if (dp->flags & CACHE_FLAG_CANEXIST) 02373 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 02374 if (dp->flags & CACHE_FLAG_PENDING) 02375 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 02376 if (dp->flags & CACHE_FLAG_TIMEOUT) 02377 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 02378 if (dp->flags & CACHE_FLAG_TRANSMITTED) 02379 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 02380 if (dp->flags & CACHE_FLAG_MATCHMORE) 02381 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 02382 if (dp->flags & CACHE_FLAG_UNKNOWN) 02383 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 02384 /* Trim trailing pipe */ 02385 if (!ast_strlen_zero(tmp)) 02386 tmp[strlen(tmp) - 1] = '\0'; 02387 else 02388 ast_copy_string(tmp, "(none)", sizeof(tmp)); 02389 y=0; 02390 pc = strchr(dp->peercontext, '@'); 02391 if (!pc) 02392 pc = dp->peercontext; 02393 else 02394 pc++; 02395 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 02396 if (dp->waiters[x] > -1) 02397 y++; 02398 if (s > 0) 02399 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 02400 else 02401 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 02402 dp = dp->next; 02403 } 02404 ast_mutex_unlock(&dpcache_lock); 02405 return RESULT_SUCCESS; 02406 }
static int iax2_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4653 of file chan_iax2.c.
References iax2_registry::addr, ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, iax2_registry::callno, jb_info::current, iax_rr::delay, FORMAT, FORMAT2, IAX_MAX_CALLS, IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), jb_info::jitter, jb_info::min, chan_iax2_pvt::remote_rr, RESULT_SHOWUSAGE, RESULT_SUCCESS, and S_OR.
04654 { 04655 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" 04656 #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" 04657 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 04658 int x; 04659 int numchans = 0; 04660 04661 if (argc != 3) 04662 return RESULT_SHOWUSAGE; 04663 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format"); 04664 for (x=0;x<IAX_MAX_CALLS;x++) { 04665 ast_mutex_lock(&iaxsl[x]); 04666 if (iaxs[x]) { 04667 int lag, jitter, localdelay; 04668 jb_info jbinfo; 04669 04670 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04671 jb_getinfo(iaxs[x]->jb, &jbinfo); 04672 jitter = jbinfo.jitter; 04673 localdelay = jbinfo.current - jbinfo.min; 04674 } else { 04675 jitter = -1; 04676 localdelay = 0; 04677 } 04678 lag = iaxs[x]->remote_rr.delay; 04679 ast_cli(fd, FORMAT, 04680 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04681 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 04682 S_OR(iaxs[x]->username, "(None)"), 04683 iaxs[x]->callno, iaxs[x]->peercallno, 04684 iaxs[x]->oseqno, iaxs[x]->iseqno, 04685 lag, 04686 jitter, 04687 localdelay, 04688 ast_getformatname(iaxs[x]->voiceformat) ); 04689 numchans++; 04690 } 04691 ast_mutex_unlock(&iaxsl[x]); 04692 } 04693 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04694 return RESULT_SUCCESS; 04695 #undef FORMAT 04696 #undef FORMAT2 04697 #undef FORMATB 04698 }
static int iax2_show_firmware | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4564 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.
04565 { 04566 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" 04567 #if !defined(__FreeBSD__) 04568 #define FORMAT "%-15.15s %-15d %-15d\n" 04569 #else /* __FreeBSD__ */ 04570 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */ 04571 #endif /* __FreeBSD__ */ 04572 struct iax_firmware *cur; 04573 if ((argc != 3) && (argc != 4)) 04574 return RESULT_SHOWUSAGE; 04575 ast_mutex_lock(&waresl.lock); 04576 04577 ast_cli(fd, FORMAT2, "Device", "Version", "Size"); 04578 for (cur = waresl.wares;cur;cur = cur->next) { 04579 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 04580 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version), 04581 (int)ntohl(cur->fwh->datalen)); 04582 } 04583 ast_mutex_unlock(&waresl.lock); 04584 return RESULT_SUCCESS; 04585 #undef FORMAT 04586 #undef FORMAT2 04587 }
static int iax2_show_netstats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4776 of file chan_iax2.c.
References ast_cli(), ast_cli_netstats(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04777 { 04778 int numchans = 0; 04779 if (argc != 3) 04780 return RESULT_SHOWUSAGE; 04781 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 04782 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n"); 04783 numchans = ast_cli_netstats(NULL, fd, 1); 04784 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04785 return RESULT_SUCCESS; 04786 }
static int iax2_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 2244 of file chan_iax2.c.
References iax2_peer::addr, ast_callerid_merge(), ast_cli(), ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, iax2_peer::capability, iax2_peer::defaddr, iax2_peer::expire, find_peer(), iax2_peer::ha, IAX_DYNAMIC, peer_status(), peer_unref(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax2_peer::prefs, RESULT_SHOWUSAGE, RESULT_SUCCESS, and iax2_peer::smoothing.
02245 { 02246 char status[30]; 02247 char cbuf[256]; 02248 struct iax2_peer *peer; 02249 char codec_buf[512]; 02250 int x = 0, codec = 0, load_realtime = 0; 02251 02252 if (argc < 4) 02253 return RESULT_SHOWUSAGE; 02254 02255 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 02256 02257 peer = find_peer(argv[3], load_realtime); 02258 if (peer) { 02259 ast_cli(fd,"\n\n"); 02260 ast_cli(fd, " * Name : %s\n", peer->name); 02261 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 02262 ast_cli(fd, " Context : %s\n", peer->context); 02263 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 02264 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No"); 02265 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 02266 ast_cli(fd, " Expire : %d\n", peer->expire); 02267 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 02268 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)); 02269 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 02270 ast_cli(fd, " Username : %s\n", peer->username); 02271 ast_cli(fd, " Codecs : "); 02272 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 02273 ast_cli(fd, "%s\n", codec_buf); 02274 02275 ast_cli(fd, " Codec Order : ("); 02276 for(x = 0; x < 32 ; x++) { 02277 codec = ast_codec_pref_index(&peer->prefs,x); 02278 if(!codec) 02279 break; 02280 ast_cli(fd, "%s", ast_getformatname(codec)); 02281 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 02282 ast_cli(fd, "|"); 02283 } 02284 02285 if (!x) 02286 ast_cli(fd, "none"); 02287 ast_cli(fd, ")\n"); 02288 02289 ast_cli(fd, " Status : "); 02290 peer_status(peer, status, sizeof(status)); 02291 ast_cli(fd, "%s\n",status); 02292 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 02293 ast_cli(fd,"\n"); 02294 peer_unref(peer); 02295 } else { 02296 ast_cli(fd,"Peer %s not found.\n", argv[3]); 02297 ast_cli(fd,"\n"); 02298 } 02299 02300 return RESULT_SUCCESS; 02301 }
static int iax2_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4553 of file chan_iax2.c.
References __iax2_show_peers().
04554 { 04555 return __iax2_show_peers(0, fd, NULL, argc, argv); 04556 }
static int iax2_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4625 of file chan_iax2.c.
References iax2_registry::addr, ast_cli(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax2_registry::dnsmgr, FORMAT, FORMAT2, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_registry::us, and iax2_registry::username.
04626 { 04627 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 04628 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 04629 struct iax2_registry *reg = NULL; 04630 04631 char host[80]; 04632 char perceived[80]; 04633 if (argc != 3) 04634 return RESULT_SHOWUSAGE; 04635 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 04636 AST_LIST_LOCK(®istrations); 04637 AST_LIST_TRAVERSE(®istrations, reg, entry) { 04638 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 04639 if (reg->us.sin_addr.s_addr) 04640 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 04641 else 04642 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 04643 ast_cli(fd, FORMAT, host, 04644 (reg->dnsmgr) ? "Y" : "N", 04645 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 04646 } 04647 AST_LIST_UNLOCK(®istrations); 04648 return RESULT_SUCCESS; 04649 #undef FORMAT 04650 #undef FORMAT2 04651 }
static int iax2_show_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2328 of file chan_iax2.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax_frame::final, iax_get_frames(), iax_get_iframes(), iax_get_oframes(), iaxq, RESULT_SHOWUSAGE, RESULT_SUCCESS, and iax_frame::retries.
02329 { 02330 struct iax_frame *cur; 02331 int cnt = 0, dead=0, final=0; 02332 02333 if (argc != 3) 02334 return RESULT_SHOWUSAGE; 02335 02336 AST_LIST_LOCK(&iaxq.queue); 02337 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 02338 if (cur->retries < 0) 02339 dead++; 02340 if (cur->final) 02341 final++; 02342 cnt++; 02343 } 02344 AST_LIST_UNLOCK(&iaxq.queue); 02345 02346 ast_cli(fd, " IAX Statistics\n"); 02347 ast_cli(fd, "---------------------\n"); 02348 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 02349 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 02350 02351 return RESULT_SUCCESS; 02352 }
static int iax2_show_threads | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4494 of file chan_iax2.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, IAX_TYPE_DYNAMIC, iaxthreadcount, RESULT_SHOWUSAGE, RESULT_SUCCESS, t, and thread.
04495 { 04496 struct iax2_thread *thread = NULL; 04497 time_t t; 04498 int threadcount = 0, dynamiccount = 0; 04499 char type; 04500 04501 if (argc != 3) 04502 return RESULT_SHOWUSAGE; 04503 04504 ast_cli(fd, "IAX2 Thread Information\n"); 04505 time(&t); 04506 ast_cli(fd, "Idle Threads:\n"); 04507 AST_LIST_LOCK(&idle_list); 04508 AST_LIST_TRAVERSE(&idle_list, thread, list) { 04509 #ifdef DEBUG_SCHED_MULTITHREAD 04510 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04511 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04512 #else 04513 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04514 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04515 #endif 04516 threadcount++; 04517 } 04518 AST_LIST_UNLOCK(&idle_list); 04519 ast_cli(fd, "Active Threads:\n"); 04520 AST_LIST_LOCK(&active_list); 04521 AST_LIST_TRAVERSE(&active_list, thread, list) { 04522 if (thread->type == IAX_TYPE_DYNAMIC) 04523 type = 'D'; 04524 else 04525 type = 'P'; 04526 #ifdef DEBUG_SCHED_MULTITHREAD 04527 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 04528 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04529 #else 04530 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 04531 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04532 #endif 04533 threadcount++; 04534 } 04535 AST_LIST_UNLOCK(&active_list); 04536 ast_cli(fd, "Dynamic Threads:\n"); 04537 AST_LIST_LOCK(&dynamic_list); 04538 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 04539 #ifdef DEBUG_SCHED_MULTITHREAD 04540 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04541 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04542 #else 04543 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04544 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04545 #endif 04546 dynamiccount++; 04547 } 04548 AST_LIST_UNLOCK(&dynamic_list); 04549 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 04550 return RESULT_SUCCESS; 04551 }
static int iax2_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4311 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_cli(), ast_strlen_zero(), ast_test_flag, iax2_user::authmethods, iax2_context::context, iax2_user::contexts, FORMAT, FORMAT2, iax2_user::ha, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, RESULT_SHOWUSAGE, RESULT_SUCCESS, user_unref(), and users.
04312 { 04313 regex_t regexbuf; 04314 int havepattern = 0; 04315 04316 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 04317 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 04318 04319 struct iax2_user *user = NULL; 04320 char auth[90]; 04321 char *pstr = ""; 04322 struct ao2_iterator i; 04323 04324 switch (argc) { 04325 case 5: 04326 if (!strcasecmp(argv[3], "like")) { 04327 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04328 return RESULT_SHOWUSAGE; 04329 havepattern = 1; 04330 } else 04331 return RESULT_SHOWUSAGE; 04332 case 3: 04333 break; 04334 default: 04335 return RESULT_SHOWUSAGE; 04336 } 04337 04338 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 04339 i = ao2_iterator_init(users, 0); 04340 for (user = ao2_iterator_next(&i); user; 04341 user_unref(user), user = ao2_iterator_next(&i)) { 04342 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 04343 continue; 04344 04345 if (!ast_strlen_zero(user->secret)) { 04346 ast_copy_string(auth,user->secret,sizeof(auth)); 04347 } else if (!ast_strlen_zero(user->inkeys)) { 04348 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 04349 } else 04350 ast_copy_string(auth, "-no secret-", sizeof(auth)); 04351 04352 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 04353 pstr = "REQ Only"; 04354 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 04355 pstr = "Disabled"; 04356 else 04357 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 04358 04359 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 04360 user->contexts ? user->contexts->context : context, 04361 user->ha ? "Yes" : "No", pstr); 04362 } 04363 04364 if (havepattern) 04365 regfree(®exbuf); 04366 04367 return RESULT_SUCCESS; 04368 #undef FORMAT 04369 #undef FORMAT2 04370 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 3332 of file chan_iax2.c.
References iax2_registry::addr, AST_FRAME_IAX, ast_random(), iax_ie_data::buf, IAX_COMMAND_TXREQ, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), IAX_IE_CALLNO, IAX_IE_TRANSFERID, iaxs, iax_ie_data::pos, send_command(), TRANSFER_BEGIN, TRANSFER_MBEGIN, and chan_iax2_pvt::transferring.
Referenced by iax2_bridge().
03333 { 03334 int res; 03335 struct iax_ie_data ied0; 03336 struct iax_ie_data ied1; 03337 unsigned int transferid = (unsigned int)ast_random(); 03338 memset(&ied0, 0, sizeof(ied0)); 03339 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 03340 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 03341 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 03342 03343 memset(&ied1, 0, sizeof(ied1)); 03344 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 03345 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 03346 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 03347 03348 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 03349 if (res) 03350 return -1; 03351 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 03352 if (res) 03353 return -1; 03354 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03355 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03356 return 0; 03357 }
static int iax2_test_losspct | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2175 of file chan_iax2.c.
References RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02176 { 02177 if (argc != 4) 02178 return RESULT_SHOWUSAGE; 02179 02180 test_losspct = atoi(argv[3]); 02181 02182 return RESULT_SUCCESS; 02183 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 3567 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), iax_ie_data::buf, iax2_registry::callno, IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, LOG_DEBUG, option_debug, iax_ie_data::pos, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03568 { 03569 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03570 struct iax_ie_data ied; 03571 char tmp[256], *context; 03572 ast_copy_string(tmp, dest, sizeof(tmp)); 03573 context = strchr(tmp, '@'); 03574 if (context) { 03575 *context = '\0'; 03576 context++; 03577 } 03578 memset(&ied, 0, sizeof(ied)); 03579 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 03580 if (context) 03581 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 03582 if (option_debug) 03583 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest); 03584 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 03585 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2634 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, AST_PTHREADT_NULL, iaxq, iax_frame::sentyet, and signal_condition().
Referenced by iax2_send().
02635 { 02636 /* Lock the queue and place this packet at the end */ 02637 /* By setting this to 0, the network thread will send it for us, and 02638 queue retransmission if necessary */ 02639 fr->sentyet = 0; 02640 AST_LIST_LOCK(&iaxq.queue); 02641 AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list); 02642 iaxq.count++; 02643 AST_LIST_UNLOCK(&iaxq.queue); 02644 /* Wake up the network and scheduler thread */ 02645 if (netthreadid != AST_PTHREADT_NULL) 02646 pthread_kill(netthreadid, SIGURG); 02647 signal_condition(&sched_lock, &sched_cond); 02648 return 0; 02649 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 6384 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
06385 { 06386 /* Drop when trunk is about 5 seconds idle */ 06387 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 06388 return 1; 06389 return 0; 06390 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 3911 of file chan_iax2.c.
References iax2_trunk_peer::addr, chan_iax2_pvt::addr, iax_frame::af, ast_inet_ntoa(), ast_log(), ast_mutex_unlock(), ast_realloc, ast_test_flag, ast_iax2_meta_trunk_entry::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, iax2_trunk_peer::calls, ast_frame::data, ast_frame::datalen, DEFAULT_TRUNKDATA, f, find_tpeer(), IAX2_TRUNK_PREFACE, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_DEBUG, LOG_WARNING, MAX_TRUNKDATA, ast_iax2_meta_trunk_mini::mini, option_debug, chan_iax2_pvt::sockfd, iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdataalloc, iax2_trunk_peer::trunkdatalen, iax_frame::ts, and ast_iax2_mini_hdr::ts.
Referenced by iax2_send().
03912 { 03913 struct ast_frame *f; 03914 struct iax2_trunk_peer *tpeer; 03915 void *tmp, *ptr; 03916 struct ast_iax2_meta_trunk_entry *met; 03917 struct ast_iax2_meta_trunk_mini *mtm; 03918 03919 f = &fr->af; 03920 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 03921 if (tpeer) { 03922 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 03923 /* Need to reallocate space */ 03924 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) { 03925 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 03926 ast_mutex_unlock(&tpeer->lock); 03927 return -1; 03928 } 03929 03930 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 03931 tpeer->trunkdata = tmp; 03932 if (option_debug) 03933 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); 03934 } else { 03935 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)); 03936 ast_mutex_unlock(&tpeer->lock); 03937 return -1; 03938 } 03939 } 03940 03941 /* Append to meta frame */ 03942 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 03943 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 03944 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 03945 mtm->len = htons(f->datalen); 03946 mtm->mini.callno = htons(pvt->callno); 03947 mtm->mini.ts = htons(0xffff & fr->ts); 03948 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 03949 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 03950 } else { 03951 met = (struct ast_iax2_meta_trunk_entry *)ptr; 03952 /* Store call number and length in meta header */ 03953 met->callno = htons(pvt->callno); 03954 met->len = htons(f->datalen); 03955 /* Advance pointers/decrease length past trunk entry header */ 03956 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 03957 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 03958 } 03959 /* Copy actual trunk data */ 03960 memcpy(ptr, f->data, f->datalen); 03961 tpeer->trunkdatalen += f->datalen; 03962 03963 tpeer->calls++; 03964 ast_mutex_unlock(&tpeer->lock); 03965 } 03966 return 0; 03967 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 6301 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, iaxs, and send_command_immediate().
Referenced by socket_process().
06302 { 06303 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 06304 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 4843 of file chan_iax2.c.
References AST_FRAME_NULL, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, iax2_registry::callno, errno, error(), ast_frame::frametype, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, iaxsl, LOG_DEBUG, option_debug, PTR_TO_CALLNO, and ast_channel::tech_pvt.
04844 { 04845 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04846 int res = -1; 04847 ast_mutex_lock(&iaxsl[callno]); 04848 if (iaxs[callno]) { 04849 /* If there's an outstanding error, return failure now */ 04850 if (!iaxs[callno]->error) { 04851 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 04852 res = 0; 04853 /* Don't waste bandwidth sending null frames */ 04854 else if (f->frametype == AST_FRAME_NULL) 04855 res = 0; 04856 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 04857 res = 0; 04858 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 04859 res = 0; 04860 else 04861 /* Simple, just queue for transmission */ 04862 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 04863 } else { 04864 if (option_debug) 04865 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); 04866 } 04867 } 04868 /* If it's already gone, just return */ 04869 ast_mutex_unlock(&iaxsl[callno]); 04870 return res; 04871 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 1701 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().
01702 { 01703 int res = 0; 01704 struct iax_firmware *cur; 01705 if (!ast_strlen_zero(dev)) { 01706 ast_mutex_lock(&waresl.lock); 01707 cur = waresl.wares; 01708 while(cur) { 01709 if (!strcmp(dev, (char *)cur->fwh->devname)) { 01710 res = ntohs(cur->fwh->version); 01711 break; 01712 } 01713 cur = cur->next; 01714 } 01715 ast_mutex_unlock(&waresl.lock); 01716 } 01717 return res; 01718 }
static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 768 of file chan_iax2.c.
References ast_verbose().
Referenced by load_module().
00769 { 00770 if (iaxdebug) 00771 ast_verbose("%s", data); 00772 }
static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 774 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
00775 { 00776 ast_log(LOG_WARNING, "%s", data); 00777 }
static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
const unsigned char * | dev, | |||
unsigned int | desc | |||
) | [static] |
Definition at line 1720 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().
01721 { 01722 int res = -1; 01723 unsigned int bs = desc & 0xff; 01724 unsigned int start = (desc >> 8) & 0xffffff; 01725 unsigned int bytes; 01726 struct iax_firmware *cur; 01727 if (!ast_strlen_zero((char *)dev) && bs) { 01728 start *= bs; 01729 ast_mutex_lock(&waresl.lock); 01730 cur = waresl.wares; 01731 while(cur) { 01732 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) { 01733 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 01734 if (start < ntohl(cur->fwh->datalen)) { 01735 bytes = ntohl(cur->fwh->datalen) - start; 01736 if (bytes > bs) 01737 bytes = bs; 01738 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 01739 } else { 01740 bytes = 0; 01741 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 01742 } 01743 if (bytes == bs) 01744 res = 0; 01745 else 01746 res = 1; 01747 break; 01748 } 01749 cur = cur->next; 01750 } 01751 ast_mutex_unlock(&waresl.lock); 01752 } 01753 return res; 01754 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2 | |||
) | [static] |
Definition at line 6567 of file chan_iax2.c.
References ast_channel::amaflags, ast_calloc, ast_channel_alloc(), ast_channel_masquerade(), ast_do_masquerade(), ast_hangup(), ast_log(), ast_pthread_create_background, AST_STATE_DOWN, iax_dual::chan1, iax_dual::chan2, ast_channel::context, ast_channel::exten, free, iax_park_thread(), LOG_WARNING, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat.
Referenced by socket_process().
06568 { 06569 struct iax_dual *d; 06570 struct ast_channel *chan1m, *chan2m; 06571 pthread_t th; 06572 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 06573 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name); 06574 if (chan2m && chan1m) { 06575 /* Make formats okay */ 06576 chan1m->readformat = chan1->readformat; 06577 chan1m->writeformat = chan1->writeformat; 06578 ast_channel_masquerade(chan1m, chan1); 06579 /* Setup the extensions and such */ 06580 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 06581 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 06582 chan1m->priority = chan1->priority; 06583 06584 /* We make a clone of the peer channel too, so we can play 06585 back the announcement */ 06586 /* Make formats okay */ 06587 chan2m->readformat = chan2->readformat; 06588 chan2m->writeformat = chan2->writeformat; 06589 ast_channel_masquerade(chan2m, chan2); 06590 /* Setup the extensions and such */ 06591 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 06592 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 06593 chan2m->priority = chan2->priority; 06594 if (ast_do_masquerade(chan2m)) { 06595 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 06596 ast_hangup(chan2m); 06597 return -1; 06598 } 06599 } else { 06600 if (chan1m) 06601 ast_hangup(chan1m); 06602 if (chan2m) 06603 ast_hangup(chan2m); 06604 return -1; 06605 } 06606 if ((d = ast_calloc(1, sizeof(*d)))) { 06607 pthread_attr_t attr; 06608 06609 pthread_attr_init(&attr); 06610 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06611 06612 d->chan1 = chan1m; 06613 d->chan2 = chan2m; 06614 if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) { 06615 pthread_attr_destroy(&attr); 06616 return 0; 06617 } 06618 pthread_attr_destroy(&attr); 06619 free(d); 06620 } 06621 return -1; 06622 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 6547 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().
06548 { 06549 struct ast_channel *chan1, *chan2; 06550 struct iax_dual *d; 06551 struct ast_frame *f; 06552 int ext; 06553 int res; 06554 d = stuff; 06555 chan1 = d->chan1; 06556 chan2 = d->chan2; 06557 free(d); 06558 f = ast_read(chan1); 06559 if (f) 06560 ast_frfree(f); 06561 res = ast_park_call(chan1, chan2, 0, &ext); 06562 ast_hangup(chan2); 06563 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 06564 return NULL; 06565 }
Definition at line 1225 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().
01226 { 01227 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01228 if (new) { 01229 size_t afdatalen = new->afdatalen; 01230 memcpy(new, fr, sizeof(*new)); 01231 iax_frame_wrap(new, &fr->af); 01232 new->afdatalen = afdatalen; 01233 new->data = NULL; 01234 new->datalen = 0; 01235 new->direction = DIRECTION_INGRESS; 01236 new->retrans = -1; 01237 } 01238 return new; 01239 }
static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 880 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, and IAX_TYPE_DYNAMIC.
Referenced by iax2_process_thread().
00881 { 00882 if (thread->type == IAX_TYPE_DYNAMIC) { 00883 AST_LIST_LOCK(&dynamic_list); 00884 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 00885 AST_LIST_UNLOCK(&dynamic_list); 00886 } else { 00887 AST_LIST_LOCK(&idle_list); 00888 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 00889 AST_LIST_UNLOCK(&idle_list); 00890 } 00891 00892 return; 00893 }
static void jb_debug_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 803 of file chan_iax2.c.
References ast_verbose().
Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug().
00804 { 00805 va_list args; 00806 char buf[1024]; 00807 00808 va_start(args, fmt); 00809 vsnprintf(buf, 1024, fmt, args); 00810 va_end(args); 00811 00812 ast_verbose(buf); 00813 }
static void jb_error_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 779 of file chan_iax2.c.
References ast_log(), and LOG_ERROR.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00780 { 00781 va_list args; 00782 char buf[1024]; 00783 00784 va_start(args, fmt); 00785 vsnprintf(buf, 1024, fmt, args); 00786 va_end(args); 00787 00788 ast_log(LOG_ERROR, buf); 00789 }
static void jb_warning_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 791 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00792 { 00793 va_list args; 00794 char buf[1024]; 00795 00796 va_start(args, fmt); 00797 vsnprintf(buf, 1024, fmt, args); 00798 va_end(args); 00799 00800 ast_log(LOG_WARNING, buf); 00801 }
static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 10867 of file chan_iax2.c.
References __unload_module(), ao2_callback(), ao2_container_alloc(), ao2_ref(), ast_channel_register(), ast_cli_register_multiple(), ast_cond_init(), ast_custom_function_register(), AST_LIST_HEAD_INIT, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_register, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, ast_mutex_init(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_register_application(), ast_register_switch(), ast_verbose(), cli_iax2, config, errno, iax2_do_register(), iax2_poke_peer_cb(), iax2_prov_app(), iax2_switch, iax2_tech, iax_debug_output(), iax_error_output(), IAX_MAX_CALLS, iax_provision_reload(), iax_set_error(), iax_set_output(), iaxpeer_function, iaxq, iaxs, iaxsl, io_context_create(), jb_error_output(), jb_setoutput(), jb_warning_output(), ast_firmware_list::lock, LOG_ERROR, LOG_WARNING, manager_iax2_show_netstats(), manager_iax2_show_peers(), MAX_PEER_BUCKETS, MAX_USER_BUCKETS, option_verbose, papp, pdescrip, peer_cmp_cb(), peer_hash_cb(), peer_set_sock_cb(), peers, psyn, reload_firmware(), sched_context_create(), set_config(), start_network_thread(), user_cmp_cb(), user_hash_cb(), users, VERBOSE_PREFIX_2, and waresl.
10868 { 10869 char *config = "iax.conf"; 10870 int res = 0; 10871 int x; 10872 struct iax2_registry *reg = NULL; 10873 10874 peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb); 10875 if (!peers) 10876 return AST_MODULE_LOAD_FAILURE; 10877 users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb); 10878 if (!users) { 10879 ao2_ref(peers, -1); 10880 return AST_MODULE_LOAD_FAILURE; 10881 } 10882 10883 ast_custom_function_register(&iaxpeer_function); 10884 10885 iax_set_output(iax_debug_output); 10886 iax_set_error(iax_error_output); 10887 jb_setoutput(jb_error_output, jb_warning_output, NULL); 10888 10889 #ifdef HAVE_ZAPTEL 10890 #ifdef ZT_TIMERACK 10891 timingfd = open("/dev/zap/timer", O_RDWR); 10892 if (timingfd < 0) 10893 #endif 10894 timingfd = open("/dev/zap/pseudo", O_RDWR); 10895 if (timingfd < 0) 10896 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno)); 10897 #endif 10898 10899 memset(iaxs, 0, sizeof(iaxs)); 10900 10901 for (x=0;x<IAX_MAX_CALLS;x++) 10902 ast_mutex_init(&iaxsl[x]); 10903 10904 ast_cond_init(&sched_cond, NULL); 10905 10906 io = io_context_create(); 10907 sched = sched_context_create(); 10908 10909 if (!io || !sched) { 10910 ast_log(LOG_ERROR, "Out of memory\n"); 10911 return -1; 10912 } 10913 10914 netsock = ast_netsock_list_alloc(); 10915 if (!netsock) { 10916 ast_log(LOG_ERROR, "Could not allocate netsock list.\n"); 10917 return -1; 10918 } 10919 ast_netsock_init(netsock); 10920 10921 outsock = ast_netsock_list_alloc(); 10922 if (!outsock) { 10923 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 10924 return -1; 10925 } 10926 ast_netsock_init(outsock); 10927 10928 ast_mutex_init(&waresl.lock); 10929 10930 AST_LIST_HEAD_INIT(&iaxq.queue); 10931 10932 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 10933 10934 ast_register_application(papp, iax2_prov_app, psyn, pdescrip); 10935 10936 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" ); 10937 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" ); 10938 10939 if(set_config(config, 0) == -1) 10940 return AST_MODULE_LOAD_DECLINE; 10941 10942 if (ast_channel_register(&iax2_tech)) { 10943 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 10944 __unload_module(); 10945 return -1; 10946 } 10947 10948 if (ast_register_switch(&iax2_switch)) 10949 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 10950 10951 res = start_network_thread(); 10952 if (!res) { 10953 if (option_verbose > 1) 10954 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n"); 10955 } else { 10956 ast_log(LOG_ERROR, "Unable to start network thread\n"); 10957 ast_netsock_release(netsock); 10958 ast_netsock_release(outsock); 10959 } 10960 10961 AST_LIST_LOCK(®istrations); 10962 AST_LIST_TRAVERSE(®istrations, reg, entry) 10963 iax2_do_register(reg); 10964 AST_LIST_UNLOCK(®istrations); 10965 10966 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 10967 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 10968 10969 reload_firmware(0); 10970 iax_provision_reload(); 10971 return res; 10972 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3359 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
03360 { 03361 ast_mutex_lock(&iaxsl[callno0]); 03362 while (ast_mutex_trylock(&iaxsl[callno1])) { 03363 ast_mutex_unlock(&iaxsl[callno0]); 03364 usleep(10); 03365 ast_mutex_lock(&iaxsl[callno0]); 03366 } 03367 }
static int make_trunk | ( | unsigned short | callno, | |
int | locked | |||
) | [static] |
Definition at line 1293 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), chan_iax2_pvt::callno, iax2_sched_add(), IAX_MAX_CALLS, iaxs, iaxsl, chan_iax2_pvt::lagid, lastused, LOG_DEBUG, LOG_WARNING, MIN_REUSE_TIME, option_debug, chan_iax2_pvt::pingid, send_lagrq(), send_ping(), TRUNK_CALL_START, update_max_nontrunk(), and update_max_trunk().
Referenced by iax2_request(), and socket_process().
01294 { 01295 int x; 01296 int res= 0; 01297 struct timeval now; 01298 if (iaxs[callno]->oseqno) { 01299 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 01300 return -1; 01301 } 01302 if (callno & TRUNK_CALL_START) { 01303 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01304 return -1; 01305 } 01306 gettimeofday(&now, NULL); 01307 for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) { 01308 ast_mutex_lock(&iaxsl[x]); 01309 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01310 iaxs[x] = iaxs[callno]; 01311 iaxs[x]->callno = x; 01312 iaxs[callno] = NULL; 01313 /* Update the two timers that should have been started */ 01314 if (iaxs[x]->pingid > -1) 01315 ast_sched_del(sched, iaxs[x]->pingid); 01316 if (iaxs[x]->lagid > -1) 01317 ast_sched_del(sched, iaxs[x]->lagid); 01318 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01319 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01320 if (locked) 01321 ast_mutex_unlock(&iaxsl[callno]); 01322 res = x; 01323 if (!locked) 01324 ast_mutex_unlock(&iaxsl[x]); 01325 break; 01326 } 01327 ast_mutex_unlock(&iaxsl[x]); 01328 } 01329 if (x >= IAX_MAX_CALLS - 1) { 01330 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01331 return -1; 01332 } 01333 if (option_debug) 01334 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x); 01335 /* We move this call from a non-trunked to a trunked call */ 01336 update_max_trunk(); 01337 update_max_nontrunk(); 01338 return res; 01339 }
static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4557 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), and RESULT_SUCCESS.
Referenced by load_module().
04558 { 04559 ast_cli_netstats(s, -1, 0); 04560 astman_append(s, "\r\n"); 04561 return RESULT_SUCCESS; 04562 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4590 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_append(), and astman_get_header().
Referenced by load_module().
04591 { 04592 char *a[] = { "iax2", "show", "users" }; 04593 int ret; 04594 const char *id = astman_get_header(m,"ActionID"); 04595 04596 if (!ast_strlen_zero(id)) 04597 astman_append(s, "ActionID: %s\r\n",id); 04598 ret = __iax2_show_peers(1, -1, s, 3, a ); 04599 astman_append(s, "\r\n\r\n" ); 04600 return ret; 04601 } /* /JDG */
static int match | ( | struct sockaddr_in * | sin, | |
unsigned short | callno, | |||
unsigned short | dcallno, | |||
struct chan_iax2_pvt * | cur, | |||
int | full_frame | |||
) | [static] |
Definition at line 1245 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::callno, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, TRANSFER_MEDIAPASS, chan_iax2_pvt::transfercallno, and chan_iax2_pvt::transferring.
Referenced by ao2_callback(), ast_parse_device_state(), find_callno(), find_command(), get_sip_pvt_byid_locked(), handle_updates(), pbx_find_extension(), realtime_switch_common(), and softhangup_exec().
01246 { 01247 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01248 (cur->addr.sin_port == sin->sin_port)) { 01249 /* This is the main host */ 01250 if ( (cur->peercallno == 0 || cur->peercallno == callno) && 01251 (full_frame ? dcallno == cur->callno : 1) ) { 01252 /* That's us. Be sure we keep track of the peer call number */ 01253 return 1; 01254 } 01255 } 01256 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01257 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01258 /* We're transferring */ 01259 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 01260 return 1; 01261 } 01262 return 0; 01263 }
static void memcpy_decrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 3975 of file chan_iax2.c.
References aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
03976 { 03977 #if 0 03978 /* Debug with "fake encryption" */ 03979 int x; 03980 if (len % 16) 03981 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 03982 for (x=0;x<len;x++) 03983 dst[x] = src[x] ^ 0xff; 03984 #else 03985 unsigned char lastblock[16] = { 0 }; 03986 int x; 03987 while(len > 0) { 03988 aes_decrypt(src, dst, dcx); 03989 for (x=0;x<16;x++) 03990 dst[x] ^= lastblock[x]; 03991 memcpy(lastblock, src, sizeof(lastblock)); 03992 dst += 16; 03993 src += 16; 03994 len -= 16; 03995 } 03996 #endif 03997 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_encrypt_ctx * | ecx | |||
) | [static] |
Definition at line 3999 of file chan_iax2.c.
References aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
04000 { 04001 #if 0 04002 /* Debug with "fake encryption" */ 04003 int x; 04004 if (len % 16) 04005 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 04006 for (x=0;x<len;x++) 04007 dst[x] = src[x] ^ 0xff; 04008 #else 04009 unsigned char curblock[16] = { 0 }; 04010 int x; 04011 while(len > 0) { 04012 for (x=0;x<16;x++) 04013 curblock[x] ^= src[x]; 04014 aes_encrypt(curblock, dst, ecx); 04015 memcpy(curblock, dst, sizeof(curblock)); 04016 dst += 16; 04017 src += 16; 04018 len -= 16; 04019 } 04020 #endif 04021 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 5168 of file chan_iax2.c.
References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.
Referenced by authenticate_reply(), and socket_process().
05169 { 05170 /* Select exactly one common encryption if there are any */ 05171 p->encmethods &= enc; 05172 if (p->encmethods) { 05173 if (p->encmethods & IAX_ENCRYPT_AES128) 05174 p->encmethods = IAX_ENCRYPT_AES128; 05175 else 05176 p->encmethods = 0; 05177 } 05178 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 8866 of file chan_iax2.c.
References ast_io_add(), AST_IO_IN, AST_IO_PRI, ast_io_wait(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), attempt_transmit(), iax_frame::callno, f, iax2_sched_add(), iax_frame_free(), iaxq, iaxs, iaxsl, LOG_DEBUG, option_debug, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_packet(), iax_frame::sentyet, and timing_read().
Referenced by start_network_thread().
08867 { 08868 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 08869 from the network, and queue them for delivery to the channels */ 08870 int res, count, wakeup; 08871 struct iax_frame *f; 08872 08873 if (timingfd > -1) 08874 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL); 08875 08876 for(;;) { 08877 pthread_testcancel(); 08878 08879 /* Go through the queue, sending messages which have not yet been 08880 sent, and scheduling retransmissions if appropriate */ 08881 AST_LIST_LOCK(&iaxq.queue); 08882 count = 0; 08883 wakeup = -1; 08884 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) { 08885 if (f->sentyet) 08886 continue; 08887 08888 /* Try to lock the pvt, if we can't... don't fret - defer it till later */ 08889 if (ast_mutex_trylock(&iaxsl[f->callno])) { 08890 wakeup = 1; 08891 continue; 08892 } 08893 08894 f->sentyet++; 08895 08896 if (iaxs[f->callno]) { 08897 send_packet(f); 08898 count++; 08899 } 08900 08901 ast_mutex_unlock(&iaxsl[f->callno]); 08902 08903 if (f->retries < 0) { 08904 /* This is not supposed to be retransmitted */ 08905 AST_LIST_REMOVE_CURRENT(&iaxq.queue, list); 08906 iaxq.count--; 08907 /* Free the iax frame */ 08908 iax_frame_free(f); 08909 } else { 08910 /* We need reliable delivery. Schedule a retransmission */ 08911 f->retries++; 08912 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 08913 } 08914 } 08915 AST_LIST_TRAVERSE_SAFE_END 08916 AST_LIST_UNLOCK(&iaxq.queue); 08917 08918 pthread_testcancel(); 08919 08920 if (option_debug && count >= 20) 08921 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 08922 08923 /* Now do the IO, and run scheduled tasks */ 08924 res = ast_io_wait(io, wakeup); 08925 if (res >= 0) { 08926 if (option_debug && res >= 20) 08927 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 08928 } 08929 } 08930 return NULL; 08931 }
static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
const char * | host | |||
) | [static, read] |
Definition at line 1187 of file chan_iax2.c.
References ast_calloc, ast_string_field_init, ast_string_field_set, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::bridgecallno, chan_iax2_pvt::callno, exten, free, chan_iax2_pvt::initid, chan_iax2_pvt::jb, jb_new(), jb_setconf(), chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, jb_conf::max_contig_interp, jb_conf::max_jitterbuf, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingid, prefs, chan_iax2_pvt::prefs, jb_conf::resync_threshold, and chan_iax2_pvt::transfercallno.
Referenced by find_callno().
01188 { 01189 struct chan_iax2_pvt *tmp; 01190 jb_conf jbconf; 01191 01192 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) 01193 return NULL; 01194 01195 if (ast_string_field_init(tmp, 32)) { 01196 free(tmp); 01197 tmp = NULL; 01198 return NULL; 01199 } 01200 01201 tmp->prefs = prefs; 01202 tmp->callno = 0; 01203 tmp->peercallno = 0; 01204 tmp->transfercallno = 0; 01205 tmp->bridgecallno = 0; 01206 tmp->pingid = -1; 01207 tmp->lagid = -1; 01208 tmp->autoid = -1; 01209 tmp->authid = -1; 01210 tmp->initid = -1; 01211 01212 ast_string_field_set(tmp,exten, "s"); 01213 ast_string_field_set(tmp,host, host); 01214 01215 tmp->jb = jb_new(); 01216 tmp->jbid = -1; 01217 jbconf.max_jitterbuf = maxjitterbuffer; 01218 jbconf.resync_threshold = resyncthreshold; 01219 jbconf.max_contig_interp = maxjitterinterps; 01220 jb_setconf(tmp->jb,&jbconf); 01221 01222 return tmp; 01223 }
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 3083 of file chan_iax2.c.
References ast_strip_quoted(), ast_strlen_zero(), parsed_dial_string::context, parsed_dial_string::exten, parsed_dial_string::key, parsed_dial_string::options, parsed_dial_string::password, parsed_dial_string::peer, parsed_dial_string::port, strsep(), and parsed_dial_string::username.
Referenced by cache_get_callno_locked(), iax2_call(), iax2_devicestate(), and iax2_request().
03084 { 03085 if (ast_strlen_zero(data)) 03086 return; 03087 03088 pds->peer = strsep(&data, "/"); 03089 pds->exten = strsep(&data, "/"); 03090 pds->options = data; 03091 03092 if (pds->exten) { 03093 data = pds->exten; 03094 pds->exten = strsep(&data, "@"); 03095 pds->context = data; 03096 } 03097 03098 if (strchr(pds->peer, '@')) { 03099 data = pds->peer; 03100 pds->username = strsep(&data, "@"); 03101 pds->peer = data; 03102 } 03103 03104 if (pds->username) { 03105 data = pds->username; 03106 pds->username = strsep(&data, ":"); 03107 pds->password = data; 03108 } 03109 03110 data = pds->peer; 03111 pds->peer = strsep(&data, ":"); 03112 pds->port = data; 03113 03114 /* check for a key name wrapped in [] in the secret position, if found, 03115 move it to the key field instead 03116 */ 03117 if (pds->password && (pds->password[0] == '[')) { 03118 pds->key = ast_strip_quoted(pds->password, "[", "]"); 03119 pds->password = NULL; 03120 } 03121 }
static int peer_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1086 of file chan_iax2.c.
Referenced by load_module().
01087 { 01088 struct iax2_peer *peer = obj, *peer2 = arg; 01089 01090 return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0; 01091 }
static int peer_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9566 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
09567 { 09568 struct iax2_peer *peer = obj; 09569 09570 ast_set_flag(peer, IAX_DELME); 09571 09572 return 0; 09573 }
static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 9089 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().
09090 { 09091 struct iax2_peer *peer = obj; 09092 09093 ast_free_ha(peer->ha); 09094 09095 if (peer->callno > 0) { 09096 ast_mutex_lock(&iaxsl[peer->callno]); 09097 iax2_destroy(peer->callno); 09098 ast_mutex_unlock(&iaxsl[peer->callno]); 09099 } 09100 09101 register_peer_exten(peer, 0); 09102 09103 if (peer->dnsmgr) 09104 ast_dnsmgr_release(peer->dnsmgr); 09105 09106 ast_string_field_free_memory(peer); 09107 }
static int peer_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1076 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_module().
01077 { 01078 const struct iax2_peer *peer = obj; 01079 01080 return ast_str_hash(peer->name); 01081 }
Definition at line 1133 of file chan_iax2.c.
References ao2_ref().
Referenced by __iax2_poke_noanswer(), iax2_poke_peer(), iax2_prune_realtime(), realtime_peer(), reg_source_db(), socket_process(), and update_registry().
01134 { 01135 ao2_ref(peer, +1); 01136 return peer; 01137 }
static int peer_set_sock_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 10856 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
10857 { 10858 struct iax2_peer *peer = obj; 10859 10860 if (peer->sockfd < 0) 10861 peer->sockfd = defaultsockfd; 10862 10863 return 0; 10864 }
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 9016 of file chan_iax2.c.
References iax2_registry::addr, ast_get_ip(), ast_log(), ast_netsock_bind(), ast_netsock_find(), ast_netsock_sockfd(), ast_netsock_unref(), ast_strdupa, check_srcaddr(), IAX_DEFAULT_PORTNO, LOG_DEBUG, LOG_WARNING, option_debug, socket_read(), iax2_peer::sockfd, and strsep().
Referenced by build_peer().
09017 { 09018 struct sockaddr_in sin; 09019 int nonlocal = 1; 09020 int port = IAX_DEFAULT_PORTNO; 09021 int sockfd = defaultsockfd; 09022 char *tmp; 09023 char *addr; 09024 char *portstr; 09025 09026 if (!(tmp = ast_strdupa(srcaddr))) 09027 return -1; 09028 09029 addr = strsep(&tmp, ":"); 09030 portstr = tmp; 09031 09032 if (portstr) { 09033 port = atoi(portstr); 09034 if (port < 1) 09035 port = IAX_DEFAULT_PORTNO; 09036 } 09037 09038 if (!ast_get_ip(&sin, addr)) { 09039 struct ast_netsock *sock; 09040 int res; 09041 09042 sin.sin_port = 0; 09043 sin.sin_family = AF_INET; 09044 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 09045 if (res == 0) { 09046 /* ip address valid. */ 09047 sin.sin_port = htons(port); 09048 if (!(sock = ast_netsock_find(netsock, &sin))) 09049 sock = ast_netsock_find(outsock, &sin); 09050 if (sock) { 09051 sockfd = ast_netsock_sockfd(sock); 09052 nonlocal = 0; 09053 } else { 09054 unsigned int orig_saddr = sin.sin_addr.s_addr; 09055 /* INADDR_ANY matches anyway! */ 09056 sin.sin_addr.s_addr = INADDR_ANY; 09057 if (ast_netsock_find(netsock, &sin)) { 09058 sin.sin_addr.s_addr = orig_saddr; 09059 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL); 09060 if (sock) { 09061 sockfd = ast_netsock_sockfd(sock); 09062 ast_netsock_unref(sock); 09063 nonlocal = 0; 09064 } else { 09065 nonlocal = 2; 09066 } 09067 } 09068 } 09069 } 09070 } 09071 09072 peer->sockfd = sockfd; 09073 09074 if (nonlocal == 1) { 09075 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 09076 srcaddr, peer->name); 09077 return -1; 09078 } else if (nonlocal == 2) { 09079 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 09080 srcaddr, peer->name); 09081 return -1; 09082 } else { 09083 if (option_debug) 09084 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 09085 return 0; 09086 } 09087 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 2221 of file chan_iax2.c.
References iax2_peer::lastms, and iax2_peer::maxms.
Referenced by __iax2_show_peers(), _sip_show_peer(), _sip_show_peers(), function_iaxpeer(), function_sippeer(), and iax2_show_peer().
02222 { 02223 int res = 0; 02224 if (peer->maxms) { 02225 if (peer->lastms < 0) { 02226 ast_copy_string(status, "UNREACHABLE", statuslen); 02227 } else if (peer->lastms > peer->maxms) { 02228 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 02229 res = 1; 02230 } else if (peer->lastms) { 02231 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 02232 res = 1; 02233 } else { 02234 ast_copy_string(status, "UNKNOWN", statuslen); 02235 } 02236 } else { 02237 ast_copy_string(status, "Unmonitored", statuslen); 02238 res = -1; 02239 } 02240 return res; 02241 }
Definition at line 1139 of file chan_iax2.c.
References ao2_ref().
Referenced by __expire_registry(), __iax2_poke_noanswer(), __iax2_poke_peer_s(), __iax2_show_peers(), authenticate_reply(), build_peer(), complete_iax2_show_peer(), create_addr(), function_iaxpeer(), iax2_devicestate(), iax2_getpeername(), iax2_getpeertrunk(), iax2_poke_noanswer(), iax2_poke_peer(), iax2_prune_realtime(), iax2_show_peer(), poke_all_peers(), prune_peers(), realtime_peer(), reg_source_db(), register_verify(), registry_authrequest(), set_config(), socket_process(), unlink_peer(), and update_registry().
01140 { 01141 ao2_ref(peer, -1); 01142 return NULL; 01143 }
static void poke_all_peers | ( | void | ) | [static] |
Definition at line 10028 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), iax2_poke_peer(), peer_unref(), and peers.
Referenced by reload_config().
10029 { 10030 struct ao2_iterator i; 10031 struct iax2_peer *peer; 10032 10033 i = ao2_iterator_init(peers, 0); 10034 while ((peer = ao2_iterator_next(&i))) { 10035 iax2_poke_peer(peer, 0); 10036 peer_unref(peer); 10037 } 10038 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 9625 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_test_flag, IAX_DELME, peer_unref(), peers, and unlink_peer().
09626 { 09627 struct iax2_peer *peer; 09628 struct ao2_iterator i; 09629 09630 i = ao2_iterator_init(peers, 0); 09631 while ((peer = ao2_iterator_next(&i))) { 09632 if (ast_test_flag(peer, IAX_DELME)) 09633 unlink_peer(peer); 09634 peer_unref(peer); 09635 } 09636 }
static void prune_users | ( | void | ) | [static] |
Definition at line 9611 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ao2_unlink(), ast_test_flag, IAX_DELME, user_unref(), and users.
Referenced by reload_config().
09612 { 09613 struct iax2_user *user; 09614 struct ao2_iterator i; 09615 09616 i = ao2_iterator_init(users, 0); 09617 while ((user = ao2_iterator_next(&i))) { 09618 if (ast_test_flag(user, IAX_DELME)) 09619 ao2_unlink(users, user); 09620 user_unref(user); 09621 } 09622 }
static int raw_hangup | ( | struct sockaddr_in * | sin, | |
unsigned short | src, | |||
unsigned short | dst, | |||
int | sockfd | |||
) | [static] |
Definition at line 5150 of file chan_iax2.c.
References AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), compress_subclass(), ast_iax2_full_hdr::csub, ast_iax2_full_hdr::dcallno, IAX_COMMAND_INVAL, IAX_FLAG_FULL, iax_showframe(), ast_iax2_full_hdr::iseqno, LOG_DEBUG, option_debug, ast_iax2_full_hdr::oseqno, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::ts, and ast_iax2_full_hdr::type.
Referenced by socket_process().
05151 { 05152 struct ast_iax2_full_hdr fh; 05153 fh.scallno = htons(src | IAX_FLAG_FULL); 05154 fh.dcallno = htons(dst); 05155 fh.ts = 0; 05156 fh.oseqno = 0; 05157 fh.iseqno = 0; 05158 fh.type = AST_FRAME_IAX; 05159 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 05160 if (iaxdebug) 05161 iax_showframe(NULL, &fh, 0, sin, 0); 05162 if (option_debug) 05163 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n", 05164 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 05165 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 05166 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static, read] |
Definition at line 2696 of file chan_iax2.c.
References iax2_peer::addr, ast_copy_flags, ast_dnsmgr_lookup(), ast_get_time_t(), ast_inet_ntoa(), ast_load_realtime(), ast_log(), ast_sched_del(), ast_set_flag, ast_test_flag, ast_variables_destroy(), build_peer(), iax2_registry::dnsmgr, iax2_peer::expire, expire_registry(), iax2_sched_add(), IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_TEMPONLY, LOG_DEBUG, ast_variable::name, ast_variable::next, option_debug, peer_ref(), peer_unref(), peers, realtime_update_peer(), reg_source_db(), ast_variable::value, and var.
02697 { 02698 struct ast_variable *var = NULL; 02699 struct ast_variable *tmp; 02700 struct iax2_peer *peer=NULL; 02701 time_t regseconds = 0, nowtime; 02702 int dynamic=0; 02703 02704 if (peername) { 02705 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL); 02706 if (!var && sin) 02707 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr)); 02708 } else if (sin) { 02709 char porta[25]; 02710 sprintf(porta, "%d", ntohs(sin->sin_port)); 02711 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02712 if (var) { 02713 /* We'll need the peer name in order to build the structure! */ 02714 for (tmp = var; tmp; tmp = tmp->next) { 02715 if (!strcasecmp(tmp->name, "name")) 02716 peername = tmp->value; 02717 } 02718 } 02719 } 02720 if (!var && peername) { /* Last ditch effort */ 02721 var = ast_load_realtime("iaxpeers", "name", peername, NULL); 02722 /*!\note 02723 * If this one loaded something, then we need to ensure that the host 02724 * field matched. The only reason why we can't have this as a criteria 02725 * is because we only have the IP address and the host field might be 02726 * set as a name (and the reverse PTR might not match). 02727 */ 02728 if (var && sin) { 02729 for (tmp = var; tmp; tmp = tmp->next) { 02730 if (!strcasecmp(tmp->name, "host")) { 02731 struct in_addr sin2 = { 0, }; 02732 struct ast_dnsmgr_entry *dnsmgr = NULL; 02733 if ((ast_dnsmgr_lookup(tmp->value, &sin2, &dnsmgr) < 0) || (memcmp(&sin2, &sin->sin_addr, sizeof(sin2)) != 0)) { 02734 /* No match */ 02735 ast_variables_destroy(var); 02736 var = NULL; 02737 } 02738 break; 02739 } 02740 } 02741 } 02742 } 02743 if (!var) 02744 return NULL; 02745 02746 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 02747 02748 if (!peer) { 02749 ast_variables_destroy(var); 02750 return NULL; 02751 } 02752 02753 for (tmp = var; tmp; tmp = tmp->next) { 02754 /* Make sure it's not a user only... */ 02755 if (!strcasecmp(tmp->name, "type")) { 02756 if (strcasecmp(tmp->value, "friend") && 02757 strcasecmp(tmp->value, "peer")) { 02758 /* Whoops, we weren't supposed to exist! */ 02759 peer = peer_unref(peer); 02760 break; 02761 } 02762 } else if (!strcasecmp(tmp->name, "regseconds")) { 02763 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 02764 } else if (!strcasecmp(tmp->name, "ipaddr")) { 02765 inet_aton(tmp->value, &(peer->addr.sin_addr)); 02766 } else if (!strcasecmp(tmp->name, "port")) { 02767 peer->addr.sin_port = htons(atoi(tmp->value)); 02768 } else if (!strcasecmp(tmp->name, "host")) { 02769 if (!strcasecmp(tmp->value, "dynamic")) 02770 dynamic = 1; 02771 } 02772 } 02773 02774 ast_variables_destroy(var); 02775 02776 if (!peer) 02777 return NULL; 02778 02779 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02780 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 02781 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 02782 if (peer->expire > -1) { 02783 if (!ast_sched_del(sched, peer->expire)) { 02784 peer->expire = -1; 02785 peer_unref(peer); 02786 } 02787 } 02788 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 02789 if (peer->expire == -1) 02790 peer_unref(peer); 02791 } 02792 ao2_link(peers, peer); 02793 if (ast_test_flag(peer, IAX_DYNAMIC)) 02794 reg_source_db(peer); 02795 } else { 02796 ast_set_flag(peer, IAX_TEMPONLY); 02797 } 02798 02799 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 02800 time(&nowtime); 02801 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 02802 memset(&peer->addr, 0, sizeof(peer->addr)); 02803 realtime_update_peer(peer->name, &peer->addr, 0); 02804 if (option_debug) 02805 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 02806 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02807 } 02808 else { 02809 if (option_debug) 02810 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 02811 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02812 } 02813 } 02814 02815 return peer; 02816 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
time_t | regtime | |||
) | [static] |
Definition at line 2889 of file chan_iax2.c.
References ast_inet_ntoa(), and ast_update_realtime().
Referenced by __expire_registry(), realtime_peer(), update_peer(), and update_registry().
02890 { 02891 char port[10]; 02892 char regseconds[20]; 02893 02894 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 02895 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02896 ast_update_realtime("iaxpeers", "name", peername, 02897 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 02898 "regseconds", regseconds, NULL); 02899 }
static struct iax2_user* realtime_user | ( | const char * | username, | |
struct sockaddr_in * | sin | |||
) | [static, read] |
Definition at line 2818 of file chan_iax2.c.
References ast_dnsmgr_lookup(), ast_inet_ntoa(), ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), build_user(), iax2_registry::dnsmgr, IAX_RTCACHEFRIENDS, IAX_TEMPONLY, ast_variable::name, ast_variable::next, users, ast_variable::value, and var.
02819 { 02820 struct ast_variable *var; 02821 struct ast_variable *tmp; 02822 struct iax2_user *user=NULL; 02823 02824 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL); 02825 if (!var) 02826 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr)); 02827 if (!var && sin) { 02828 char porta[6]; 02829 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 02830 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02831 if (!var) 02832 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02833 } 02834 if (!var) { /* Last ditch effort */ 02835 var = ast_load_realtime("iaxusers", "name", username, NULL); 02836 /*!\note 02837 * If this one loaded something, then we need to ensure that the host 02838 * field matched. The only reason why we can't have this as a criteria 02839 * is because we only have the IP address and the host field might be 02840 * set as a name (and the reverse PTR might not match). 02841 */ 02842 if (var) { 02843 for (tmp = var; tmp; tmp = tmp->next) { 02844 if (!strcasecmp(tmp->name, "host")) { 02845 struct in_addr sin2 = { 0, }; 02846 struct ast_dnsmgr_entry *dnsmgr = NULL; 02847 if ((ast_dnsmgr_lookup(tmp->value, &sin2, &dnsmgr) < 0) || (memcmp(&sin2, &sin->sin_addr, sizeof(sin2)) != 0)) { 02848 /* No match */ 02849 ast_variables_destroy(var); 02850 var = NULL; 02851 } 02852 break; 02853 } 02854 } 02855 } 02856 } 02857 if (!var) 02858 return NULL; 02859 02860 tmp = var; 02861 while(tmp) { 02862 /* Make sure it's not a peer only... */ 02863 if (!strcasecmp(tmp->name, "type")) { 02864 if (strcasecmp(tmp->value, "friend") && 02865 strcasecmp(tmp->value, "user")) { 02866 return NULL; 02867 } 02868 } 02869 tmp = tmp->next; 02870 } 02871 02872 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 02873 02874 ast_variables_destroy(var); 02875 02876 if (!user) 02877 return NULL; 02878 02879 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02880 ast_set_flag(user, IAX_RTCACHEFRIENDS); 02881 ao2_link(users, user); 02882 } else { 02883 ast_set_flag(user, IAX_TEMPONLY); 02884 } 02885 02886 return user; 02887 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 5932 of file chan_iax2.c.
References iax2_peer::addr, ast_db_get(), ast_device_state_changed(), ast_inet_ntoa(), ast_sched_del(), ast_test_flag, ast_verbose(), iax2_peer::expire, expire_registry(), iax2_peer::expiry, iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), IAX_TEMPONLY, option_verbose, peer_ref(), peer_unref(), register_peer_exten(), and VERBOSE_PREFIX_3.
Referenced by build_peer(), realtime_peer(), set_config(), and temp_peer().
05933 { 05934 char data[80]; 05935 struct in_addr in; 05936 char *c, *d; 05937 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 05938 c = strchr(data, ':'); 05939 if (c) { 05940 *c = '\0'; 05941 c++; 05942 if (inet_aton(data, &in)) { 05943 d = strchr(c, ':'); 05944 if (d) { 05945 *d = '\0'; 05946 d++; 05947 if (option_verbose > 2) 05948 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 05949 ast_inet_ntoa(in), atoi(c), atoi(d)); 05950 iax2_poke_peer(p, 0); 05951 p->expiry = atoi(d); 05952 memset(&p->addr, 0, sizeof(p->addr)); 05953 p->addr.sin_family = AF_INET; 05954 p->addr.sin_addr = in; 05955 p->addr.sin_port = htons(atoi(c)); 05956 if (p->expire > -1) { 05957 if (!ast_sched_del(sched, p->expire)) { 05958 p->expire = -1; 05959 peer_unref(p); 05960 } 05961 } 05962 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05963 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 05964 if (p->expire == -1) 05965 peer_unref(p); 05966 if (iax2_regfunk) 05967 iax2_regfunk(p->name, 1); 05968 register_peer_exten(p, 1); 05969 } 05970 05971 } 05972 } 05973 } 05974 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 5852 of file chan_iax2.c.
References ast_add_extension(), ast_context_remove_extension(), ast_exists_extension(), ast_free, ast_strdup, ast_strlen_zero(), ext, S_OR, and strsep().
Referenced by __expire_registry(), expire_register(), parse_register_contact(), peer_destructor(), reg_source_db(), sip_destroy_peer(), and update_registry().
05853 { 05854 char multi[256]; 05855 char *stringp, *ext; 05856 if (!ast_strlen_zero(regcontext)) { 05857 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 05858 stringp = multi; 05859 while((ext = strsep(&stringp, "&"))) { 05860 if (onoff) { 05861 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 05862 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 05863 "Noop", ast_strdup(peer->name), ast_free, "IAX2"); 05864 } else 05865 ast_context_remove_extension(regcontext, ext, 1, NULL); 05866 } 05867 } 05868 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 5314 of file chan_iax2.c.
References iax2_peer::addr, ast_apply_ha(), ast_check_signature, ast_clear_flag, ast_device_state_changed(), ast_inet_ntoa(), ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, iax2_peer::authmethods, iax2_registry::expire, chan_iax2_pvt::expiry, expiry, find_peer(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, IAX_STATE_UNCHANGED, iaxs, iaxsl, inaddrcmp(), key(), LOG_NOTICE, LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax_ies::password, peer_unref(), iax_ies::refresh, iax_ies::rsa_result, iax2_registry::secret, strsep(), and iax_ies::username.
Referenced by handle_request_register(), and socket_process().
05315 { 05316 char requeststr[256] = ""; 05317 char peer[256] = ""; 05318 char md5secret[256] = ""; 05319 char rsasecret[256] = ""; 05320 char secret[256] = ""; 05321 struct iax2_peer *p = NULL; 05322 struct ast_key *key; 05323 char *keyn; 05324 int x; 05325 int expire = 0; 05326 int res = -1; 05327 05328 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED); 05329 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 05330 if (ies->username) 05331 ast_copy_string(peer, ies->username, sizeof(peer)); 05332 if (ies->password) 05333 ast_copy_string(secret, ies->password, sizeof(secret)); 05334 if (ies->md5_result) 05335 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05336 if (ies->rsa_result) 05337 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05338 if (ies->refresh) 05339 expire = ies->refresh; 05340 05341 if (ast_strlen_zero(peer)) { 05342 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 05343 return -1; 05344 } 05345 05346 /* SLD: first call to lookup peer during registration */ 05347 ast_mutex_unlock(&iaxsl[callno]); 05348 p = find_peer(peer, 1); 05349 ast_mutex_lock(&iaxsl[callno]); 05350 if (!p || !iaxs[callno]) { 05351 if (iaxs[callno]) { 05352 ast_string_field_set(iaxs[callno], secret, "badsecret"); 05353 } 05354 if (authdebug && !p) 05355 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05356 goto return_unref; 05357 } 05358 05359 if (!ast_test_flag(p, IAX_DYNAMIC)) { 05360 if (authdebug) 05361 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05362 goto return_unref; 05363 } 05364 05365 if (!ast_apply_ha(p->ha, sin)) { 05366 if (authdebug) 05367 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05368 goto return_unref; 05369 } 05370 if (!inaddrcmp(&p->addr, sin)) 05371 ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED); 05372 ast_string_field_set(iaxs[callno], secret, p->secret); 05373 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 05374 /* Check secret against what we have on file */ 05375 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05376 if (!ast_strlen_zero(p->inkeys)) { 05377 char tmpkeys[256]; 05378 char *stringp=NULL; 05379 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 05380 stringp=tmpkeys; 05381 keyn = strsep(&stringp, ":"); 05382 while(keyn) { 05383 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05384 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 05385 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05386 break; 05387 } else if (!key) 05388 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 05389 keyn = strsep(&stringp, ":"); 05390 } 05391 if (!keyn) { 05392 if (authdebug) 05393 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 05394 goto return_unref; 05395 } 05396 } else { 05397 if (authdebug) 05398 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 05399 goto return_unref; 05400 } 05401 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05402 struct MD5Context md5; 05403 unsigned char digest[16]; 05404 char *tmppw, *stringp; 05405 05406 tmppw = ast_strdupa(p->secret); 05407 stringp = tmppw; 05408 while((tmppw = strsep(&stringp, ";"))) { 05409 MD5Init(&md5); 05410 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 05411 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05412 MD5Final(digest, &md5); 05413 for (x=0;x<16;x++) 05414 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05415 if (!strcasecmp(requeststr, md5secret)) 05416 break; 05417 } 05418 if (tmppw) { 05419 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05420 } else { 05421 if (authdebug) 05422 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 05423 goto return_unref; 05424 } 05425 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 05426 /* They've provided a plain text password and we support that */ 05427 if (strcmp(secret, p->secret)) { 05428 if (authdebug) 05429 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05430 goto return_unref; 05431 } else 05432 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05433 } else if (!ast_strlen_zero(iaxs[callno]->secret) || !ast_strlen_zero(iaxs[callno]->inkeys)) { 05434 if (authdebug && 05435 ((!ast_strlen_zero(iaxs[callno]->secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) || 05436 (!ast_strlen_zero(iaxs[callno]->inkeys) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)))) { 05437 ast_log(LOG_NOTICE, "Inappropriate authentication received for '%s'\n", p->name); 05438 } /* ELSE this is the first time through and no challenge exists, so it's not quite yet a failure. */ 05439 goto return_unref; 05440 } 05441 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05442 05443 return_unref: 05444 ast_string_field_set(iaxs[callno], peer, peer); 05445 /* Choose lowest expiry number */ 05446 if (expire && (expire < iaxs[callno]->expiry)) 05447 iaxs[callno]->expiry = expire; 05448 05449 res = 0; 05450 05451 if (p) 05452 peer_unref(p); 05453 05454 return res; 05455 }
static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 6111 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, iax_ie_data::buf, 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(), iax_ie_data::pos, and send_command().
Referenced by socket_process().
06112 { 06113 struct iax_ie_data ied; 06114 struct iax2_peer *p; 06115 char challenge[10]; 06116 const char *peer_name; 06117 int sentauthmethod; 06118 06119 peer_name = ast_strdupa(iaxs[callno]->peer); 06120 06121 /* SLD: third call to find_peer in registration */ 06122 ast_mutex_unlock(&iaxsl[callno]); 06123 if ((p = find_peer(peer_name, 1))) { 06124 last_authmethod = p->authmethods; 06125 } 06126 06127 ast_mutex_lock(&iaxsl[callno]); 06128 if (!iaxs[callno]) 06129 goto return_unref; 06130 06131 memset(&ied, 0, sizeof(ied)); 06132 /* The selection of which delayed reject is sent may leak information, 06133 * if it sets a static response. For example, if a host is known to only 06134 * use MD5 authentication, then an RSA response would indicate that the 06135 * peer does not exist, and vice-versa. 06136 * Therefore, we use whatever the last peer used (which may vary over the 06137 * course of a server, which should leak minimal information). */ 06138 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 06139 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod); 06140 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 06141 /* Build the challenge */ 06142 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 06143 ast_string_field_set(iaxs[callno], challenge, challenge); 06144 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 06145 } 06146 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 06147 06148 return_unref: 06149 if (p) { 06150 peer_unref(p); 06151 } 06152 06153 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1; 06154 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 6156 of file chan_iax2.c.
References iax2_registry::addr, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_strlen_zero(), authenticate(), iax_ies::authmethods, iax_ie_data::buf, iax_ies::challenge, IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax_ie_data::pos, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_AUTHSENT, REG_STATE_NOAUTH, iax2_registry::regstate, iax2_registry::secret, send_command(), iax2_registry::username, and iax_ies::username.
Referenced by socket_process().
06157 { 06158 struct iax2_registry *reg; 06159 /* Start pessimistic */ 06160 struct iax_ie_data ied; 06161 char peer[256] = ""; 06162 char challenge[256] = ""; 06163 int res; 06164 int authmethods = 0; 06165 if (ies->authmethods) 06166 authmethods = ies->authmethods; 06167 if (ies->username) 06168 ast_copy_string(peer, ies->username, sizeof(peer)); 06169 if (ies->challenge) 06170 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 06171 memset(&ied, 0, sizeof(ied)); 06172 reg = iaxs[callno]->reg; 06173 if (reg) { 06174 if (inaddrcmp(®->addr, sin)) { 06175 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 06176 return -1; 06177 } 06178 if (ast_strlen_zero(reg->secret)) { 06179 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 06180 reg->regstate = REG_STATE_NOAUTH; 06181 return -1; 06182 } 06183 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 06184 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 06185 if (reg->secret[0] == '[') { 06186 char tmpkey[256]; 06187 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 06188 tmpkey[strlen(tmpkey) - 1] = '\0'; 06189 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL); 06190 } else 06191 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL); 06192 if (!res) { 06193 reg->regstate = REG_STATE_AUTHSENT; 06194 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 06195 } else 06196 return -1; 06197 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 06198 } else 06199 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 06200 return -1; 06201 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 4603 of file chan_iax2.c.
References REG_STATE_AUTHSENT, REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REGSENT, REG_STATE_REJECTED, REG_STATE_TIMEOUT, and REG_STATE_UNREGISTERED.
Referenced by handle_response_register(), iax2_show_registry(), sip_reg_timeout(), and sip_show_registry().
04604 { 04605 switch(regstate) { 04606 case REG_STATE_UNREGISTERED: 04607 return "Unregistered"; 04608 case REG_STATE_REGSENT: 04609 return "Request Sent"; 04610 case REG_STATE_AUTHSENT: 04611 return "Auth. Sent"; 04612 case REG_STATE_REGISTERED: 04613 return "Registered"; 04614 case REG_STATE_REJECTED: 04615 return "Rejected"; 04616 case REG_STATE_TIMEOUT: 04617 return "Timeout"; 04618 case REG_STATE_NOAUTH: 04619 return "No Authentication"; 04620 default: 04621 return "Unknown"; 04622 } 04623 }
static int reload | ( | void | ) | [static] |
Definition at line 10065 of file chan_iax2.c.
References reload_config().
10066 { 10067 return reload_config(); 10068 }
static int reload_config | ( | void | ) | [static] |
Definition at line 10039 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, config, iax2_do_register(), iax_provision_reload(), poke_all_peers(), prune_peers(), prune_users(), reload_firmware(), and set_config().
10040 { 10041 char *config = "iax.conf"; 10042 struct iax2_registry *reg; 10043 10044 if (set_config(config, 1) > 0) { 10045 prune_peers(); 10046 prune_users(); 10047 AST_LIST_LOCK(®istrations); 10048 AST_LIST_TRAVERSE(®istrations, reg, entry) 10049 iax2_do_register(reg); 10050 AST_LIST_UNLOCK(®istrations); 10051 /* Qualify hosts, too */ 10052 poke_all_peers(); 10053 } 10054 reload_firmware(0); 10055 iax_provision_reload(); 10056 10057 return 0; 10058 }
static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 1757 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().
01758 { 01759 struct iax_firmware *cur, *curl, *curp; 01760 DIR *fwd; 01761 struct dirent *de; 01762 char dir[256]; 01763 char fn[256]; 01764 /* Mark all as dead */ 01765 ast_mutex_lock(&waresl.lock); 01766 cur = waresl.wares; 01767 while(cur) { 01768 cur->dead = 1; 01769 cur = cur->next; 01770 } 01771 01772 /* Now that we've freed them, load the new ones */ 01773 if (!unload) { 01774 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR); 01775 fwd = opendir(dir); 01776 if (fwd) { 01777 while((de = readdir(fwd))) { 01778 if (de->d_name[0] != '.') { 01779 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 01780 if (!try_firmware(fn)) { 01781 if (option_verbose > 1) 01782 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name); 01783 } 01784 } 01785 } 01786 closedir(fwd); 01787 } else 01788 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 01789 } 01790 01791 /* Clean up leftovers */ 01792 cur = waresl.wares; 01793 curp = NULL; 01794 while(cur) { 01795 curl = cur; 01796 cur = cur->next; 01797 if (curl->dead) { 01798 if (curp) { 01799 curp->next = cur; 01800 } else { 01801 waresl.wares = cur; 01802 } 01803 destroy_firmware(curl); 01804 } else { 01805 curp = cur; 01806 } 01807 } 01808 ast_mutex_unlock(&waresl.lock); 01809 }
Definition at line 6657 of file chan_iax2.c.
References iax_frame::callno, iax_rr::delay, iax_rr::dropped, iaxs, iax_rr::jitter, iax_rr::losscnt, iax_rr::losspct, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::remote_rr, iax_ies::rr_delay, iax_ies::rr_dropped, iax_ies::rr_jitter, iax_ies::rr_loss, iax_ies::rr_ooo, and iax_ies::rr_pkts.
Referenced by socket_process().
06658 { 06659 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 06660 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 06661 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 06662 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 06663 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 06664 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 06665 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 06666 }
static void* sched_thread | ( | void * | ignore | ) | [static] |
Definition at line 8838 of file chan_iax2.c.
References ast_cond_timedwait(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_runq(), ast_sched_wait(), ast_tvadd(), LOG_DEBUG, and option_debug.
Referenced by start_network_thread().
08839 { 08840 int count; 08841 int res; 08842 struct timeval tv; 08843 struct timespec ts; 08844 08845 for (;;) { 08846 res = ast_sched_wait(sched); 08847 if ((res > 1000) || (res < 0)) 08848 res = 1000; 08849 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000)); 08850 ts.tv_sec = tv.tv_sec; 08851 ts.tv_nsec = tv.tv_usec * 1000; 08852 08853 pthread_testcancel(); 08854 ast_mutex_lock(&sched_lock); 08855 ast_cond_timedwait(&sched_cond, &sched_lock, &ts); 08856 ast_mutex_unlock(&sched_lock); 08857 pthread_testcancel(); 08858 08859 count = ast_sched_runq(sched); 08860 if (option_debug && count >= 20) 08861 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 08862 } 08863 return NULL; 08864 }
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 2549 of file chan_iax2.c.
References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_codec_get_samples(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_log(), ast_sched_del(), ast_test_flag, ast_tvadd(), calc_rxstamp(), iax_frame::callno, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, chan_iax2_pvt::jb, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, chan_iax2_pvt::jbid, len, LOG_DEBUG, option_debug, chan_iax2_pvt::owner, ast_channel_tech::properties, chan_iax2_pvt::rxcore, ast_channel::tech, iax_frame::ts, unwrap_timestamp(), and update_jbsched().
Referenced by socket_process().
02550 { 02551 int type, len; 02552 int ret; 02553 int needfree = 0; 02554 02555 /* Attempt to recover wrapped timestamps */ 02556 unwrap_timestamp(fr); 02557 02558 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 02559 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 02560 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 02561 else { 02562 #if 0 02563 if (option_debug) 02564 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 02565 #endif 02566 fr->af.delivery = ast_tv(0,0); 02567 } 02568 02569 type = JB_TYPE_CONTROL; 02570 len = 0; 02571 02572 if(fr->af.frametype == AST_FRAME_VOICE) { 02573 type = JB_TYPE_VOICE; 02574 len = ast_codec_get_samples(&fr->af) / 8; 02575 } else if(fr->af.frametype == AST_FRAME_CNG) { 02576 type = JB_TYPE_SILENCE; 02577 } 02578 02579 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 02580 if (tsout) 02581 *tsout = fr->ts; 02582 __do_deliver(fr); 02583 return -1; 02584 } 02585 02586 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 02587 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 02588 if( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && 02589 iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && 02590 (ast_bridged_channel(iaxs[fr->callno]->owner)->tech->properties & AST_CHAN_TP_WANTSJITTER)) { 02591 jb_frame frame; 02592 02593 /* deliver any frames in the jb */ 02594 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 02595 __do_deliver(frame.data); 02596 /* __do_deliver() can make the call disappear */ 02597 if (!iaxs[fr->callno]) 02598 return -1; 02599 } 02600 02601 jb_reset(iaxs[fr->callno]->jb); 02602 02603 if (iaxs[fr->callno]->jbid > -1) 02604 ast_sched_del(sched, iaxs[fr->callno]->jbid); 02605 02606 iaxs[fr->callno]->jbid = -1; 02607 02608 /* deliver this frame now */ 02609 if (tsout) 02610 *tsout = fr->ts; 02611 __do_deliver(fr); 02612 return -1; 02613 } 02614 02615 /* insert into jitterbuffer */ 02616 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 02617 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 02618 calc_rxstamp(iaxs[fr->callno],fr->ts)); 02619 if (ret == JB_DROP) { 02620 needfree++; 02621 } else if (ret == JB_SCHED) { 02622 update_jbsched(iaxs[fr->callno]); 02623 } 02624 if (tsout) 02625 *tsout = fr->ts; 02626 if (needfree) { 02627 /* Free our iax frame */ 02628 iax2_frame_free(fr); 02629 return -1; 02630 } 02631 return 0; 02632 }
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 3056 of file chan_iax2.c.
References AST_FRAME_IAX, compress_subclass(), and ast_iax2_full_hdr::scallno.
Referenced by socket_process().
03057 { 03058 struct ast_iax2_full_hdr f = { .scallno = htons(0x8000 | callno), .dcallno = htons(dcallno), 03059 .ts = htonl(ts), .iseqno = seqno, .oseqno = 0, .type = AST_FRAME_IAX, 03060 .csub = compress_subclass(command) }; 03061 03062 return sendto(defaultsockfd, &f, sizeof(f), 0, (struct sockaddr *)sin, sizeof(*sin)); 03063 }
static int send_command | ( | struct chan_iax2_pvt * | i, | |
char | type, | |||
int | command, | |||
unsigned int | ts, | |||
const unsigned char * | data, | |||
int | datalen, | |||
int | seqno | |||
) | [static] |
Definition at line 4887 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().
04888 { 04889 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 04890 }
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 4906 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().
04907 { 04908 int call_num = i->callno; 04909 /* It is assumed that the callno has already been locked */ 04910 iax2_predestroy(i->callno); 04911 if (!iaxs[call_num]) 04912 return -1; 04913 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 04914 }
static int send_command_immediate | ( | struct chan_iax2_pvt * | i, | |
char | type, | |||
int | command, | |||
unsigned int | ts, | |||
const unsigned char * | data, | |||
int | datalen, | |||
int | seqno | |||
) | [static] |
Definition at line 4916 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
04917 { 04918 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 04919 }
static int send_command_locked | ( | unsigned short | callno, | |
char | type, | |||
int | command, | |||
unsigned int | ts, | |||
const unsigned char * | data, | |||
int | datalen, | |||
int | seqno | |||
) | [static] |
Definition at line 4892 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().
04893 { 04894 int res; 04895 ast_mutex_lock(&iaxsl[callno]); 04896 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 04897 ast_mutex_unlock(&iaxsl[callno]); 04898 return res; 04899 }
static int send_command_transfer | ( | struct chan_iax2_pvt * | i, | |
char | type, | |||
int | command, | |||
unsigned int | ts, | |||
const unsigned char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 4921 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
04922 { 04923 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 04924 }
static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1030 of file chan_iax2.c.
References __send_lagrq(), and schedule_action.
Referenced by __send_lagrq(), find_callno(), and make_trunk().
01031 { 01032 #ifdef SCHED_MULTITHREADED 01033 if (schedule_action(__send_lagrq, data)) 01034 #endif 01035 __send_lagrq(data); 01036 return 0; 01037 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 1882 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax2_registry::addr, ast_inet_ntoa(), ast_log(), iax_frame::callno, iax2_registry::callno, iax_frame::data, iax_frame::datalen, errno, error(), handle_error(), iax_showframe(), iaxs, LOG_DEBUG, option_debug, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, transfer, iax_frame::transfer, and iax_frame::ts.
Referenced by __attempt_transmit(), iax2_send(), network_thread(), and vnak_retransmit().
01883 { 01884 int res; 01885 int callno = f->callno; 01886 01887 /* Don't send if there was an error, but return error instead */ 01888 if (!callno || !iaxs[callno] || iaxs[callno]->error) 01889 return -1; 01890 01891 /* Called with iaxsl held */ 01892 if (option_debug > 2 && iaxdebug) 01893 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)); 01894 if (f->transfer) { 01895 if (iaxdebug) 01896 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 01897 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, 01898 sizeof(iaxs[callno]->transfer)); 01899 } else { 01900 if (iaxdebug) 01901 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 01902 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, 01903 sizeof(iaxs[callno]->addr)); 01904 } 01905 if (res < 0) { 01906 if (option_debug && iaxdebug) 01907 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 01908 handle_error(); 01909 } else 01910 res = 0; 01911 return res; 01912 }
static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 995 of file chan_iax2.c.
References __send_ping(), and schedule_action.
Referenced by __send_ping(), find_callno(), and make_trunk().
00996 { 00997 #ifdef SCHED_MULTITHREADED 00998 if (schedule_action(__send_ping, data)) 00999 #endif 01000 __send_ping(data); 01001 return 0; 01002 }
static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [static] |
Definition at line 6340 of file chan_iax2.c.
References iax2_trunk_peer::addr, iax_frame::afdata, ast_inet_ntoa(), ast_log(), ast_test_flag, calc_txpeerstamp(), iax2_trunk_peer::calls, ast_iax2_meta_hdr::cmddata, iax_frame::data, ast_iax2_meta_hdr::data, iax_frame::datalen, iax_frame::direction, DIRECTION_OUTGRESS, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, LOG_DEBUG, ast_iax2_meta_hdr::metacmd, option_debug, iax_frame::retrans, iax2_trunk_peer::sockfd, iax_frame::transfer, transmit_trunk(), iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdatalen, ast_iax2_meta_trunk_hdr::ts, and ast_iax2_meta_hdr::zeros.
Referenced by timing_read().
06341 { 06342 int res = 0; 06343 struct iax_frame *fr; 06344 struct ast_iax2_meta_hdr *meta; 06345 struct ast_iax2_meta_trunk_hdr *mth; 06346 int calls = 0; 06347 06348 /* Point to frame */ 06349 fr = (struct iax_frame *)tpeer->trunkdata; 06350 /* Point to meta data */ 06351 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 06352 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 06353 if (tpeer->trunkdatalen) { 06354 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 06355 meta->zeros = 0; 06356 meta->metacmd = IAX_META_TRUNK; 06357 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 06358 meta->cmddata = IAX_META_TRUNK_MINI; 06359 else 06360 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 06361 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 06362 /* And the rest of the ast_iax2 header */ 06363 fr->direction = DIRECTION_OUTGRESS; 06364 fr->retrans = -1; 06365 fr->transfer = 0; 06366 /* Any appropriate call will do */ 06367 fr->data = fr->afdata; 06368 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 06369 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 06370 calls = tpeer->calls; 06371 #if 0 06372 if (option_debug) 06373 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)); 06374 #endif 06375 /* Reset transmit trunk side data */ 06376 tpeer->trunkdatalen = 0; 06377 tpeer->calls = 0; 06378 } 06379 if (res < 0) 06380 return res; 06381 return calls; 06382 }
static int set_config | ( | char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 9669 of file chan_iax2.c.
References __ao2_link(), ast_category_browse(), ast_cdr_amaflags2int(), ast_clear_flag, ast_config_destroy(), ast_config_load(), ast_context_create(), ast_context_find(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_netsock_bind(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_netsock_sockfd(), ast_netsock_unref(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_str2tos(), ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), build_peer(), build_user(), capability, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), iax2_register(), IAX_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, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_PEER_BUCKETS, ast_variable::name, ast_variable::next, option_verbose, peer_unref(), peers, portno, prefs, reg_source_db(), iax2_registry::secret, set_config_destroy(), set_timing(), socket_read(), user_unref(), users, ast_variable::value, and VERBOSE_PREFIX_2.
Referenced by load_module(), reload(), and reload_config().
09670 { 09671 struct ast_config *cfg, *ucfg; 09672 int capability=iax2_capability; 09673 struct ast_variable *v; 09674 char *cat; 09675 const char *utype; 09676 const char *tosval; 09677 int format; 09678 int portno = IAX_DEFAULT_PORTNO; 09679 int x; 09680 struct iax2_user *user; 09681 struct iax2_peer *peer; 09682 struct ast_netsock *ns; 09683 #if 0 09684 static unsigned short int last_port=0; 09685 #endif 09686 09687 cfg = ast_config_load(config_file); 09688 09689 if (!cfg) { 09690 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 09691 return -1; 09692 } 09693 09694 if (reload) { 09695 set_config_destroy(); 09696 } 09697 09698 /* Reset global codec prefs */ 09699 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 09700 09701 /* Reset Global Flags */ 09702 memset(&globalflags, 0, sizeof(globalflags)); 09703 ast_set_flag(&globalflags, IAX_RTUPDATE); 09704 09705 #ifdef SO_NO_CHECK 09706 nochecksums = 0; 09707 #endif 09708 09709 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 09710 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 09711 09712 maxauthreq = 3; 09713 09714 v = ast_variable_browse(cfg, "general"); 09715 09716 /* Seed initial tos value */ 09717 tosval = ast_variable_retrieve(cfg, "general", "tos"); 09718 if (tosval) { 09719 if (ast_str2tos(tosval, &tos)) 09720 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n"); 09721 } 09722 while(v) { 09723 if (!strcasecmp(v->name, "bindport")){ 09724 if (reload) 09725 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 09726 else 09727 portno = atoi(v->value); 09728 } else if (!strcasecmp(v->name, "pingtime")) 09729 ping_time = atoi(v->value); 09730 else if (!strcasecmp(v->name, "iaxthreadcount")) { 09731 if (reload) { 09732 if (atoi(v->value) != iaxthreadcount) 09733 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 09734 } else { 09735 iaxthreadcount = atoi(v->value); 09736 if (iaxthreadcount < 1) { 09737 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 09738 iaxthreadcount = 1; 09739 } else if (iaxthreadcount > 256) { 09740 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 09741 iaxthreadcount = 256; 09742 } 09743 } 09744 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 09745 if (reload) { 09746 AST_LIST_LOCK(&dynamic_list); 09747 iaxmaxthreadcount = atoi(v->value); 09748 AST_LIST_UNLOCK(&dynamic_list); 09749 } else { 09750 iaxmaxthreadcount = atoi(v->value); 09751 if (iaxmaxthreadcount < 0) { 09752 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 09753 iaxmaxthreadcount = 0; 09754 } else if (iaxmaxthreadcount > 256) { 09755 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 09756 iaxmaxthreadcount = 256; 09757 } 09758 } 09759 } else if (!strcasecmp(v->name, "nochecksums")) { 09760 #ifdef SO_NO_CHECK 09761 if (ast_true(v->value)) 09762 nochecksums = 1; 09763 else 09764 nochecksums = 0; 09765 #else 09766 if (ast_true(v->value)) 09767 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 09768 #endif 09769 } 09770 else if (!strcasecmp(v->name, "maxjitterbuffer")) 09771 maxjitterbuffer = atoi(v->value); 09772 else if (!strcasecmp(v->name, "resyncthreshold")) 09773 resyncthreshold = atoi(v->value); 09774 else if (!strcasecmp(v->name, "maxjitterinterps")) 09775 maxjitterinterps = atoi(v->value); 09776 else if (!strcasecmp(v->name, "lagrqtime")) 09777 lagrq_time = atoi(v->value); 09778 else if (!strcasecmp(v->name, "maxregexpire")) 09779 max_reg_expire = atoi(v->value); 09780 else if (!strcasecmp(v->name, "minregexpire")) 09781 min_reg_expire = atoi(v->value); 09782 else if (!strcasecmp(v->name, "bindaddr")) { 09783 if (reload) { 09784 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 09785 } else { 09786 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) { 09787 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 09788 } else { 09789 if (option_verbose > 1) { 09790 if (strchr(v->value, ':')) 09791 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value); 09792 else 09793 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno); 09794 } 09795 if (defaultsockfd < 0) 09796 defaultsockfd = ast_netsock_sockfd(ns); 09797 ast_netsock_unref(ns); 09798 } 09799 } 09800 } else if (!strcasecmp(v->name, "authdebug")) 09801 authdebug = ast_true(v->value); 09802 else if (!strcasecmp(v->name, "encryption")) 09803 iax2_encryption = get_encrypt_methods(v->value); 09804 else if (!strcasecmp(v->name, "notransfer")) { 09805 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09806 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 09807 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER); 09808 } else if (!strcasecmp(v->name, "transfer")) { 09809 if (!strcasecmp(v->value, "mediaonly")) { 09810 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09811 } else if (ast_true(v->value)) { 09812 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09813 } else 09814 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09815 } else if (!strcasecmp(v->name, "codecpriority")) { 09816 if(!strcasecmp(v->value, "caller")) 09817 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 09818 else if(!strcasecmp(v->value, "disabled")) 09819 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 09820 else if(!strcasecmp(v->value, "reqonly")) { 09821 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 09822 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 09823 } 09824 } else if (!strcasecmp(v->name, "jitterbuffer")) 09825 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 09826 else if (!strcasecmp(v->name, "forcejitterbuffer")) 09827 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 09828 else if (!strcasecmp(v->name, "delayreject")) 09829 delayreject = ast_true(v->value); 09830 else if (!strcasecmp(v->name, "allowfwdownload")) 09831 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 09832 else if (!strcasecmp(v->name, "rtcachefriends")) 09833 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 09834 else if (!strcasecmp(v->name, "rtignoreregexpire")) 09835 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 09836 else if (!strcasecmp(v->name, "rtupdate")) 09837 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 09838 else if (!strcasecmp(v->name, "trunktimestamps")) 09839 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 09840 else if (!strcasecmp(v->name, "rtautoclear")) { 09841 int i = atoi(v->value); 09842 if(i > 0) 09843 global_rtautoclear = i; 09844 else 09845 i = 0; 09846 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 09847 } else if (!strcasecmp(v->name, "trunkfreq")) { 09848 trunkfreq = atoi(v->value); 09849 if (trunkfreq < 10) 09850 trunkfreq = 10; 09851 } else if (!strcasecmp(v->name, "autokill")) { 09852 if (sscanf(v->value, "%d", &x) == 1) { 09853 if (x >= 0) 09854 autokill = x; 09855 else 09856 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 09857 } else if (ast_true(v->value)) { 09858 autokill = DEFAULT_MAXMS; 09859 } else { 09860 autokill = 0; 09861 } 09862 } else if (!strcasecmp(v->name, "bandwidth")) { 09863 if (!strcasecmp(v->value, "low")) { 09864 capability = IAX_CAPABILITY_LOWBANDWIDTH; 09865 } else if (!strcasecmp(v->value, "medium")) { 09866 capability = IAX_CAPABILITY_MEDBANDWIDTH; 09867 } else if (!strcasecmp(v->value, "high")) { 09868 capability = IAX_CAPABILITY_FULLBANDWIDTH; 09869 } else 09870 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 09871 } else if (!strcasecmp(v->name, "allow")) { 09872 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 09873 } else if (!strcasecmp(v->name, "disallow")) { 09874 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 09875 } else if (!strcasecmp(v->name, "register")) { 09876 iax2_register(v->value, v->lineno); 09877 } else if (!strcasecmp(v->name, "iaxcompat")) { 09878 iaxcompat = ast_true(v->value); 09879 } else if (!strcasecmp(v->name, "regcontext")) { 09880 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 09881 /* Create context if it doesn't exist already */ 09882 if (!ast_context_find(regcontext)) 09883 ast_context_create(NULL, regcontext, "IAX2"); 09884 } else if (!strcasecmp(v->name, "tos")) { 09885 if (ast_str2tos(v->value, &tos)) 09886 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno); 09887 } else if (!strcasecmp(v->name, "accountcode")) { 09888 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 09889 } else if (!strcasecmp(v->name, "mohinterpret")) { 09890 ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret)); 09891 } else if (!strcasecmp(v->name, "mohsuggest")) { 09892 ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest)); 09893 } else if (!strcasecmp(v->name, "amaflags")) { 09894 format = ast_cdr_amaflags2int(v->value); 09895 if (format < 0) { 09896 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 09897 } else { 09898 amaflags = format; 09899 } 09900 } else if (!strcasecmp(v->name, "language")) { 09901 ast_copy_string(language, v->value, sizeof(language)); 09902 } else if (!strcasecmp(v->name, "maxauthreq")) { 09903 maxauthreq = atoi(v->value); 09904 if (maxauthreq < 0) 09905 maxauthreq = 0; 09906 } else if (!strcasecmp(v->name, "adsi")) { 09907 adsi = ast_true(v->value); 09908 } /*else if (strcasecmp(v->name,"type")) */ 09909 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09910 v = v->next; 09911 } 09912 09913 if (defaultsockfd < 0) { 09914 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) { 09915 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 09916 } else { 09917 if (option_verbose > 1) 09918 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 09919 defaultsockfd = ast_netsock_sockfd(ns); 09920 ast_netsock_unref(ns); 09921 } 09922 } 09923 if (reload) { 09924 ast_netsock_release(outsock); 09925 outsock = ast_netsock_list_alloc(); 09926 if (!outsock) { 09927 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 09928 return -1; 09929 } 09930 ast_netsock_init(outsock); 09931 } 09932 09933 if (min_reg_expire > max_reg_expire) { 09934 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 09935 min_reg_expire, max_reg_expire, max_reg_expire); 09936 min_reg_expire = max_reg_expire; 09937 } 09938 iax2_capability = capability; 09939 09940 ucfg = ast_config_load("users.conf"); 09941 if (ucfg) { 09942 struct ast_variable *gen; 09943 int genhasiax; 09944 int genregisteriax; 09945 const char *hasiax, *registeriax; 09946 09947 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 09948 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 09949 gen = ast_variable_browse(ucfg, "general"); 09950 cat = ast_category_browse(ucfg, NULL); 09951 while (cat) { 09952 if (strcasecmp(cat, "general")) { 09953 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 09954 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 09955 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 09956 /* Start with general parameters, then specific parameters, user and peer */ 09957 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 09958 if (user) { 09959 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 09960 user = user_unref(user); 09961 } 09962 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 09963 if (peer) { 09964 if (ast_test_flag(peer, IAX_DYNAMIC)) 09965 reg_source_db(peer); 09966 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 09967 peer = peer_unref(peer); 09968 } 09969 } 09970 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 09971 char tmp[256]; 09972 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 09973 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 09974 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 09975 if (!host) 09976 host = ast_variable_retrieve(ucfg, "general", "host"); 09977 if (!username) 09978 username = ast_variable_retrieve(ucfg, "general", "username"); 09979 if (!secret) 09980 secret = ast_variable_retrieve(ucfg, "general", "secret"); 09981 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 09982 if (!ast_strlen_zero(secret)) 09983 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 09984 else 09985 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 09986 iax2_register(tmp, 0); 09987 } 09988 } 09989 } 09990 cat = ast_category_browse(ucfg, cat); 09991 } 09992 ast_config_destroy(ucfg); 09993 } 09994 09995 cat = ast_category_browse(cfg, NULL); 09996 while(cat) { 09997 if (strcasecmp(cat, "general")) { 09998 utype = ast_variable_retrieve(cfg, cat, "type"); 09999 if (utype) { 10000 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 10001 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 10002 if (user) { 10003 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10004 user = user_unref(user); 10005 } 10006 } 10007 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 10008 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 10009 if (peer) { 10010 if (ast_test_flag(peer, IAX_DYNAMIC)) 10011 reg_source_db(peer); 10012 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10013 peer = peer_unref(peer); 10014 } 10015 } else if (strcasecmp(utype, "user")) { 10016 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 10017 } 10018 } else 10019 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 10020 } 10021 cat = ast_category_browse(cfg, cat); 10022 } 10023 ast_config_destroy(cfg); 10024 set_timing(); 10025 return 1; 10026 }
static void set_config_destroy | ( | void | ) | [static] |
Definition at line 9653 of file chan_iax2.c.
References ast_clear_flag, delete_users(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, and IAX_USEJITTERBUF.
Referenced by set_config().
09654 { 09655 strcpy(accountcode, ""); 09656 strcpy(language, ""); 09657 strcpy(mohinterpret, "default"); 09658 strcpy(mohsuggest, ""); 09659 amaflags = 0; 09660 delayreject = 0; 09661 ast_clear_flag((&globalflags), IAX_NOTRANSFER); 09662 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 09663 ast_clear_flag((&globalflags), IAX_USEJITTERBUF); 09664 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF); 09665 delete_users(); 09666 }
static void set_timing | ( | void | ) | [static] |
Definition at line 9638 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by set_config().
09639 { 09640 #ifdef HAVE_ZAPTEL 09641 int bs = trunkfreq * 8; 09642 if (timingfd > -1) { 09643 if ( 09644 #ifdef ZT_TIMERACK 09645 ioctl(timingfd, ZT_TIMERCONFIG, &bs) && 09646 #endif 09647 ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs)) 09648 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n"); 09649 } 09650 #endif 09651 }
static void signal_condition | ( | ast_mutex_t * | lock, | |
ast_cond_t * | cond | |||
) | [static] |
Definition at line 761 of file chan_iax2.c.
References ast_cond_signal(), ast_mutex_lock(), and ast_mutex_unlock().
Referenced by __schedule_action(), iax2_sched_add(), iax2_transmit(), and socket_read().
00762 { 00763 ast_mutex_lock(lock); 00764 ast_cond_signal(cond); 00765 ast_mutex_unlock(lock); 00766 }
static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 6809 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, iax_frame::afdatalen, chan_iax2_pvt::aseqno, ast_async_goto(), ast_best_codec(), ast_bridged_channel(), AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_clear_flag, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_UNHOLD, ast_device_state_changed(), ast_exists_extension(), AST_FORMAT_SLINEAR, ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_IAX, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname(), ast_iax2_new(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_parking_ext(), ast_sched_del(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), chan_iax2_pvt::authmethods, iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, calc_timestamp(), iax_ies::called_number, iax2_peer::callno, chan_iax2_pvt::callno, ast_iax2_meta_trunk_entry::callno, ast_iax2_mini_hdr::callno, iax2_registry::callno, iax_frame::callno, chan_iax2_pvt::capability, iax_ies::cause, iax_ies::causecode, check_access(), check_provisioning(), chan_iax2_pvt::chosenformat, cid_num, ast_iax2_meta_hdr::cmddata, iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), construct_rr(), ast_iax2_full_hdr::csub, ast_frame::data, ast_iax2_meta_trunk_hdr::data, ast_iax2_meta_hdr::data, ast_frame::datalen, ast_iax2_full_hdr::dcallno, decrypt_frame(), iax_ies::devicetype, dp_lookup(), chan_iax2_pvt::encmethods, iax_ies::encmethods, chan_iax2_pvt::error, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, iax_frame::final, find_callno(), find_tpeer(), fix_peerts(), iax2_dpcache::flags, iax_ies::format, format, chan_iax2_pvt::frames_received, ast_frame::frametype, iax_ies::fwdesc, ast_channel::hangupcause, iax2_peer::historicms, iax2_ack_registry(), iax2_destroy(), iax2_dprequest(), iax2_poke_peer_s(), iax2_queue_control_data(), iax2_sched_add(), iax2_send(), iax2_vnak(), IAX_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, iax_ies::iax_unknown, iaxfrdup2(), iaxq, iaxs, iaxsl, inaddrcmp(), chan_iax2_pvt::initid, chan_iax2_pvt::iseqno, iax_frame::iseqno, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::last, iax2_peer::lastms, ast_frame::len, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, len, ast_channel::lock, iax2_trunk_peer::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_trunk(), ast_frame::mallocd, manager_event(), iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, ast_iax2_meta_trunk_mini::mini, iax_ies::musiconhold, ast_channel::nativeformats, NEW_ALLOW, NEW_PREVENT, ast_frame::offset, option_debug, option_verbose, chan_iax2_pvt::oseqno, iax_frame::oseqno, ast_iax2_full_hdr::oseqno, iax_frame::outoforder, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), iax2_dpcache::peer, peer_ref(), peer_unref(), chan_iax2_pvt::peercallno, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, chan_iax2_pvt::prefs, iax_ies::provver, iax_ies::provverpres, raw_hangup(), ast_channel::readformat, iax_ies::refresh, REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), iax_frame::retries, chan_iax2_pvt::rprefs, chan_iax2_pvt::rseqno, iax2_trunk_peer::rxtrunktime, S_OR, ast_frame::samples, save_rr(), ast_iax2_full_hdr::scallno, schedule_delivery(), send_apathetic_reply(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), iax_ies::serviceident, iax2_peer::smoothing, spawn_dp_lookup(), ast_frame::src, chan_iax2_pvt::state, stop_stuff(), ast_frame::subclass, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MEDIAPASS, TRANSFER_MREADY, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, iax2_trunk_peer::trunkact, try_transfer(), ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_mini_hdr::ts, ast_iax2_meta_trunk_hdr::ts, ast_iax2_full_hdr::type, uncompress_subclass(), update_registry(), iax_ies::username, VERBOSE_PREFIX_3, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, and ast_iax2_meta_hdr::zeros.
Referenced by handle_deferred_full_frames(), and iax2_process_thread().
06810 { 06811 struct sockaddr_in sin; 06812 int res; 06813 int updatehistory=1; 06814 int new = NEW_PREVENT; 06815 void *ptr; 06816 int dcallno = 0; 06817 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 06818 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 06819 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 06820 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 06821 struct ast_iax2_meta_trunk_hdr *mth; 06822 struct ast_iax2_meta_trunk_entry *mte; 06823 struct ast_iax2_meta_trunk_mini *mtm; 06824 struct iax_frame *fr; 06825 struct iax_frame *cur; 06826 struct ast_frame f = { 0, }; 06827 struct ast_channel *c; 06828 struct iax2_dpcache *dp; 06829 struct iax2_peer *peer; 06830 struct iax2_trunk_peer *tpeer; 06831 struct timeval rxtrunktime; 06832 struct iax_ies ies; 06833 struct iax_ie_data ied0, ied1; 06834 int format; 06835 int fd; 06836 int exists; 06837 int minivid = 0; 06838 unsigned int ts; 06839 char empty[32]=""; /* Safety measure */ 06840 struct iax_frame *duped_fr; 06841 char host_pref_buf[128]; 06842 char caller_pref_buf[128]; 06843 struct ast_codec_pref pref; 06844 char *using_prefs = "mine"; 06845 06846 /* allocate an iax_frame with 4096 bytes of data buffer */ 06847 fr = alloca(sizeof(*fr) + 4096); 06848 fr->callno = 0; 06849 fr->afdatalen = 4096; /* From alloca() above */ 06850 06851 /* Copy frequently used parameters to the stack */ 06852 res = thread->buf_len; 06853 fd = thread->iofd; 06854 memcpy(&sin, &thread->iosin, sizeof(sin)); 06855 06856 if (res < sizeof(*mh)) { 06857 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh)); 06858 return 1; 06859 } 06860 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 06861 if (res < sizeof(*vh)) { 06862 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)); 06863 return 1; 06864 } 06865 06866 /* This is a video frame, get call number */ 06867 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 06868 minivid = 1; 06869 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) { 06870 unsigned char metatype; 06871 06872 if (res < sizeof(*meta)) { 06873 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)); 06874 return 1; 06875 } 06876 06877 /* This is a meta header */ 06878 switch(meta->metacmd) { 06879 case IAX_META_TRUNK: 06880 if (res < (sizeof(*meta) + sizeof(*mth))) { 06881 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res, 06882 sizeof(*meta) + sizeof(*mth)); 06883 return 1; 06884 } 06885 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 06886 ts = ntohl(mth->ts); 06887 metatype = meta->cmddata; 06888 res -= (sizeof(*meta) + sizeof(*mth)); 06889 ptr = mth->data; 06890 tpeer = find_tpeer(&sin, fd); 06891 if (!tpeer) { 06892 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)); 06893 return 1; 06894 } 06895 tpeer->trunkact = ast_tvnow(); 06896 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 06897 tpeer->rxtrunktime = tpeer->trunkact; 06898 rxtrunktime = tpeer->rxtrunktime; 06899 ast_mutex_unlock(&tpeer->lock); 06900 while(res >= sizeof(*mte)) { 06901 /* Process channels */ 06902 unsigned short callno, trunked_ts, len; 06903 06904 if (metatype == IAX_META_TRUNK_MINI) { 06905 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 06906 ptr += sizeof(*mtm); 06907 res -= sizeof(*mtm); 06908 len = ntohs(mtm->len); 06909 callno = ntohs(mtm->mini.callno); 06910 trunked_ts = ntohs(mtm->mini.ts); 06911 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 06912 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 06913 ptr += sizeof(*mte); 06914 res -= sizeof(*mte); 06915 len = ntohs(mte->len); 06916 callno = ntohs(mte->callno); 06917 trunked_ts = 0; 06918 } else { 06919 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 06920 break; 06921 } 06922 /* Stop if we don't have enough data */ 06923 if (len > res) 06924 break; 06925 fr->callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0); 06926 if (fr->callno) { 06927 ast_mutex_lock(&iaxsl[fr->callno]); 06928 /* If it's a valid call, deliver the contents. If not, we 06929 drop it, since we don't have a scallno to use for an INVAL */ 06930 /* Process as a mini frame */ 06931 memset(&f, 0, sizeof(f)); 06932 f.frametype = AST_FRAME_VOICE; 06933 if (iaxs[fr->callno]) { 06934 if (iaxs[fr->callno]->voiceformat > 0) { 06935 f.subclass = iaxs[fr->callno]->voiceformat; 06936 f.datalen = len; 06937 if (f.datalen >= 0) { 06938 if (f.datalen) 06939 f.data = ptr; 06940 if(trunked_ts) { 06941 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 06942 } else 06943 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 06944 /* Don't pass any packets until we're started */ 06945 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 06946 /* Common things */ 06947 f.src = "IAX2"; 06948 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 06949 f.samples = ast_codec_get_samples(&f); 06950 iax_frame_wrap(fr, &f); 06951 duped_fr = iaxfrdup2(fr); 06952 if (duped_fr) { 06953 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); 06954 } 06955 /* It is possible for the pvt structure to go away after we call schedule_delivery */ 06956 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 06957 iaxs[fr->callno]->last = fr->ts; 06958 #if 1 06959 if (option_debug && iaxdebug) 06960 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 06961 #endif 06962 } 06963 } 06964 } else { 06965 ast_log(LOG_WARNING, "Datalen < 0?\n"); 06966 } 06967 } else { 06968 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n "); 06969 iax2_vnak(fr->callno); 06970 } 06971 } 06972 ast_mutex_unlock(&iaxsl[fr->callno]); 06973 } 06974 ptr += len; 06975 res -= len; 06976 } 06977 06978 } 06979 return 1; 06980 } 06981 06982 #ifdef DEBUG_SUPPORT 06983 if (iaxdebug && (res >= sizeof(*fh))) 06984 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 06985 #endif 06986 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06987 if (res < sizeof(*fh)) { 06988 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)); 06989 return 1; 06990 } 06991 06992 /* Get the destination call number */ 06993 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 06994 /* Retrieve the type and subclass */ 06995 f.frametype = fh->type; 06996 if (f.frametype == AST_FRAME_VIDEO) { 06997 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 06998 } else { 06999 f.subclass = uncompress_subclass(fh->csub); 07000 } 07001 07002 /* Deal with POKE/PONG without allocating a callno */ 07003 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) { 07004 /* Reply back with a PONG, but don't care about the result. */ 07005 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohs(fh->ts), fh->iseqno + 1); 07006 return 1; 07007 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) { 07008 /* Ignore */ 07009 return 1; 07010 } 07011 07012 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) || 07013 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) || 07014 (f.subclass == IAX_COMMAND_REGREL))) 07015 new = NEW_ALLOW; 07016 } else { 07017 /* Don't know anything about it yet */ 07018 f.frametype = AST_FRAME_NULL; 07019 f.subclass = 0; 07020 } 07021 07022 if (!fr->callno) 07023 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, ntohs(mh->callno) & IAX_FLAG_FULL); 07024 07025 if (fr->callno > 0) 07026 ast_mutex_lock(&iaxsl[fr->callno]); 07027 07028 if (!fr->callno || !iaxs[fr->callno]) { 07029 /* A call arrived for a nonexistent destination. Unless it's an "inval" 07030 frame, reply with an inval */ 07031 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07032 /* We can only raw hangup control frames */ 07033 if (((f.subclass != IAX_COMMAND_INVAL) && 07034 (f.subclass != IAX_COMMAND_TXCNT) && 07035 (f.subclass != IAX_COMMAND_TXACC) && 07036 (f.subclass != IAX_COMMAND_FWDOWNL))|| 07037 (f.frametype != AST_FRAME_IAX)) 07038 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 07039 fd); 07040 } 07041 if (fr->callno > 0) 07042 ast_mutex_unlock(&iaxsl[fr->callno]); 07043 return 1; 07044 } 07045 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { 07046 if (decrypt_frame(fr->callno, fh, &f, &res)) { 07047 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 07048 ast_mutex_unlock(&iaxsl[fr->callno]); 07049 return 1; 07050 } 07051 #ifdef DEBUG_SUPPORT 07052 else if (iaxdebug) 07053 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 07054 #endif 07055 } 07056 07057 /* count this frame */ 07058 iaxs[fr->callno]->frames_received++; 07059 07060 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 07061 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 07062 f.subclass != IAX_COMMAND_TXACC) /* for attended transfer */ 07063 iaxs[fr->callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL); 07064 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07065 if (option_debug && iaxdebug) 07066 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 07067 /* Check if it's out of order (and not an ACK or INVAL) */ 07068 fr->oseqno = fh->oseqno; 07069 fr->iseqno = fh->iseqno; 07070 fr->ts = ntohl(fh->ts); 07071 #ifdef IAXTESTS 07072 if (test_resync) { 07073 if (option_debug) 07074 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 07075 fr->ts += test_resync; 07076 } 07077 #endif /* IAXTESTS */ 07078 #if 0 07079 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 07080 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 07081 (f.subclass == IAX_COMMAND_NEW || 07082 f.subclass == IAX_COMMAND_AUTHREQ || 07083 f.subclass == IAX_COMMAND_ACCEPT || 07084 f.subclass == IAX_COMMAND_REJECT)) ) ) 07085 #endif 07086 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 07087 updatehistory = 0; 07088 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 07089 (iaxs[fr->callno]->iseqno || 07090 ((f.subclass != IAX_COMMAND_TXCNT) && 07091 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 07092 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 07093 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 07094 (f.subclass != IAX_COMMAND_TXACC)) || 07095 (f.frametype != AST_FRAME_IAX))) { 07096 if ( 07097 ((f.subclass != IAX_COMMAND_ACK) && 07098 (f.subclass != IAX_COMMAND_INVAL) && 07099 (f.subclass != IAX_COMMAND_TXCNT) && 07100 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 07101 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 07102 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 07103 (f.subclass != IAX_COMMAND_TXACC) && 07104 (f.subclass != IAX_COMMAND_VNAK)) || 07105 (f.frametype != AST_FRAME_IAX)) { 07106 /* If it's not an ACK packet, it's out of order. */ 07107 if (option_debug) 07108 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 07109 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); 07110 /* Check to see if we need to request retransmission, 07111 * and take sequence number wraparound into account */ 07112 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 07113 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 07114 if ((f.frametype != AST_FRAME_IAX) || 07115 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 07116 if (option_debug) 07117 ast_log(LOG_DEBUG, "Acking anyway\n"); 07118 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 07119 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 07120 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07121 } 07122 } else { 07123 /* Send a VNAK requesting retransmission */ 07124 iax2_vnak(fr->callno); 07125 } 07126 ast_mutex_unlock(&iaxsl[fr->callno]); 07127 return 1; 07128 } 07129 } else { 07130 /* Increment unless it's an ACK or VNAK */ 07131 if (((f.subclass != IAX_COMMAND_ACK) && 07132 (f.subclass != IAX_COMMAND_INVAL) && 07133 (f.subclass != IAX_COMMAND_TXCNT) && 07134 (f.subclass != IAX_COMMAND_TXACC) && 07135 (f.subclass != IAX_COMMAND_VNAK)) || 07136 (f.frametype != AST_FRAME_IAX)) 07137 iaxs[fr->callno]->iseqno++; 07138 } 07139 /* A full frame */ 07140 if (res < sizeof(*fh)) { 07141 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh)); 07142 ast_mutex_unlock(&iaxsl[fr->callno]); 07143 return 1; 07144 } 07145 /* Ensure text frames are NULL-terminated */ 07146 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 07147 if (res < thread->buf_size) 07148 thread->buf[res++] = '\0'; 07149 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 07150 thread->buf[res - 1] = '\0'; 07151 } 07152 f.datalen = res - sizeof(*fh); 07153 07154 /* Handle implicit ACKing unless this is an INVAL, and only if this is 07155 from the real peer, not the transfer peer */ 07156 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07157 ((f.subclass != IAX_COMMAND_INVAL) || 07158 (f.frametype != AST_FRAME_IAX))) { 07159 unsigned char x; 07160 int call_to_destroy; 07161 /* XXX This code is not very efficient. Surely there is a better way which still 07162 properly handles boundary conditions? XXX */ 07163 /* First we have to qualify that the ACKed value is within our window */ 07164 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++) 07165 if (fr->iseqno == x) 07166 break; 07167 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 07168 /* The acknowledgement is within our window. Time to acknowledge everything 07169 that it says to */ 07170 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 07171 /* Ack the packet with the given timestamp */ 07172 if (option_debug && iaxdebug) 07173 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x); 07174 call_to_destroy = 0; 07175 AST_LIST_LOCK(&iaxq.queue); 07176 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07177 /* If it's our call, and our timestamp, mark -1 retries */ 07178 if ((fr->callno == cur->callno) && (x == cur->oseqno)) { 07179 cur->retries = -1; 07180 /* Destroy call if this is the end */ 07181 if (cur->final) 07182 call_to_destroy = fr->callno; 07183 } 07184 } 07185 AST_LIST_UNLOCK(&iaxq.queue); 07186 if (call_to_destroy) { 07187 if (iaxdebug && option_debug) 07188 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy); 07189 iax2_destroy(call_to_destroy); 07190 } 07191 } 07192 /* Note how much we've received acknowledgement for */ 07193 if (iaxs[fr->callno]) 07194 iaxs[fr->callno]->rseqno = fr->iseqno; 07195 else { 07196 /* Stop processing now */ 07197 ast_mutex_unlock(&iaxsl[fr->callno]); 07198 return 1; 07199 } 07200 } else if (option_debug) 07201 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 07202 } 07203 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07204 ((f.frametype != AST_FRAME_IAX) || 07205 ((f.subclass != IAX_COMMAND_TXACC) && 07206 (f.subclass != IAX_COMMAND_TXCNT)))) { 07207 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 07208 ast_mutex_unlock(&iaxsl[fr->callno]); 07209 return 1; 07210 } 07211 07212 if (f.datalen) { 07213 if (f.frametype == AST_FRAME_IAX) { 07214 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) { 07215 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 07216 ast_mutex_unlock(&iaxsl[fr->callno]); 07217 return 1; 07218 } 07219 f.data = NULL; 07220 f.datalen = 0; 07221 } else 07222 f.data = thread->buf + sizeof(*fh); 07223 } else { 07224 if (f.frametype == AST_FRAME_IAX) 07225 f.data = NULL; 07226 else 07227 f.data = empty; 07228 memset(&ies, 0, sizeof(ies)); 07229 } 07230 07231 /* when we receive the first full frame for a new incoming channel, 07232 it is safe to start the PBX on the channel because we have now 07233 completed a 3-way handshake with the peer */ 07234 if ((f.frametype == AST_FRAME_VOICE) || 07235 (f.frametype == AST_FRAME_VIDEO) || 07236 (f.frametype == AST_FRAME_IAX)) { 07237 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 07238 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07239 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) { 07240 ast_mutex_unlock(&iaxsl[fr->callno]); 07241 return 1; 07242 } 07243 } 07244 } 07245 07246 if (f.frametype == AST_FRAME_VOICE) { 07247 if (f.subclass != iaxs[fr->callno]->voiceformat) { 07248 iaxs[fr->callno]->voiceformat = f.subclass; 07249 if (option_debug) 07250 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass); 07251 if (iaxs[fr->callno]->owner) { 07252 int orignative; 07253 retryowner: 07254 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07255 ast_mutex_unlock(&iaxsl[fr->callno]); 07256 usleep(1); 07257 ast_mutex_lock(&iaxsl[fr->callno]); 07258 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner; 07259 } 07260 if (iaxs[fr->callno]) { 07261 if (iaxs[fr->callno]->owner) { 07262 orignative = iaxs[fr->callno]->owner->nativeformats; 07263 iaxs[fr->callno]->owner->nativeformats = f.subclass; 07264 if (iaxs[fr->callno]->owner->readformat) 07265 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07266 iaxs[fr->callno]->owner->nativeformats = orignative; 07267 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07268 } 07269 } else { 07270 if (option_debug) 07271 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); 07272 ast_mutex_unlock(&iaxsl[fr->callno]); 07273 return 1; 07274 } 07275 } 07276 } 07277 } 07278 if (f.frametype == AST_FRAME_VIDEO) { 07279 if (f.subclass != iaxs[fr->callno]->videoformat) { 07280 if (option_debug) 07281 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 07282 iaxs[fr->callno]->videoformat = f.subclass & ~0x1; 07283 } 07284 } 07285 if (f.frametype == AST_FRAME_IAX) { 07286 if (iaxs[fr->callno]->initid > -1) { 07287 /* Don't auto congest anymore since we've gotten something usefulb ack */ 07288 ast_sched_del(sched, iaxs[fr->callno]->initid); 07289 iaxs[fr->callno]->initid = -1; 07290 } 07291 /* Handle the IAX pseudo frame itself */ 07292 if (option_debug && iaxdebug) 07293 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); 07294 07295 /* Update last ts unless the frame's timestamp originated with us. */ 07296 if (iaxs[fr->callno]->last < fr->ts && 07297 f.subclass != IAX_COMMAND_ACK && 07298 f.subclass != IAX_COMMAND_PONG && 07299 f.subclass != IAX_COMMAND_LAGRP) { 07300 iaxs[fr->callno]->last = fr->ts; 07301 if (option_debug && iaxdebug) 07302 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07303 } 07304 07305 switch(f.subclass) { 07306 case IAX_COMMAND_ACK: 07307 /* Do nothing */ 07308 break; 07309 case IAX_COMMAND_QUELCH: 07310 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07311 /* Generate Manager Hold event, if necessary*/ 07312 if (iaxs[fr->callno]->owner) { 07313 manager_event(EVENT_FLAG_CALL, "Hold", 07314 "Channel: %s\r\n" 07315 "Uniqueid: %s\r\n", 07316 iaxs[fr->callno]->owner->name, 07317 iaxs[fr->callno]->owner->uniqueid); 07318 } 07319 07320 ast_set_flag(iaxs[fr->callno], IAX_QUELCH); 07321 if (ies.musiconhold) { 07322 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07323 const char *mohsuggest = iaxs[fr->callno]->mohsuggest; 07324 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 07325 S_OR(mohsuggest, NULL), 07326 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0); 07327 if (!iaxs[fr->callno]) { 07328 ast_mutex_unlock(&iaxsl[fr->callno]); 07329 return 1; 07330 } 07331 } 07332 } 07333 } 07334 break; 07335 case IAX_COMMAND_UNQUELCH: 07336 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07337 /* Generate Manager Unhold event, if necessary*/ 07338 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { 07339 manager_event(EVENT_FLAG_CALL, "Unhold", 07340 "Channel: %s\r\n" 07341 "Uniqueid: %s\r\n", 07342 iaxs[fr->callno]->owner->name, 07343 iaxs[fr->callno]->owner->uniqueid); 07344 } 07345 07346 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); 07347 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07348 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 07349 if (!iaxs[fr->callno]) { 07350 ast_mutex_unlock(&iaxsl[fr->callno]); 07351 return 1; 07352 } 07353 } 07354 } 07355 break; 07356 case IAX_COMMAND_TXACC: 07357 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 07358 /* Ack the packet with the given timestamp */ 07359 AST_LIST_LOCK(&iaxq.queue); 07360 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07361 /* Cancel any outstanding txcnt's */ 07362 if ((fr->callno == cur->callno) && (cur->transfer)) 07363 cur->retries = -1; 07364 } 07365 AST_LIST_UNLOCK(&iaxq.queue); 07366 memset(&ied1, 0, sizeof(ied1)); 07367 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 07368 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 07369 iaxs[fr->callno]->transferring = TRANSFER_READY; 07370 } 07371 break; 07372 case IAX_COMMAND_NEW: 07373 /* Ignore if it's already up */ 07374 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 07375 break; 07376 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 07377 ast_mutex_unlock(&iaxsl[fr->callno]); 07378 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 07379 ast_mutex_lock(&iaxsl[fr->callno]); 07380 if (!iaxs[fr->callno]) { 07381 ast_mutex_unlock(&iaxsl[fr->callno]); 07382 return 1; 07383 } 07384 } 07385 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 07386 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { 07387 int new_callno; 07388 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 07389 fr->callno = new_callno; 07390 } 07391 /* For security, always ack immediately */ 07392 if (delayreject) 07393 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07394 if (check_access(fr->callno, &sin, &ies)) { 07395 /* They're not allowed on */ 07396 auth_fail(fr->callno, IAX_COMMAND_REJECT); 07397 if (authdebug) 07398 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); 07399 break; 07400 } 07401 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 07402 const char *context, *exten, *cid_num; 07403 07404 context = ast_strdupa(iaxs[fr->callno]->context); 07405 exten = ast_strdupa(iaxs[fr->callno]->exten); 07406 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 07407 07408 /* This might re-enter the IAX code and need the lock */ 07409 ast_mutex_unlock(&iaxsl[fr->callno]); 07410 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 07411 ast_mutex_lock(&iaxsl[fr->callno]); 07412 07413 if (!iaxs[fr->callno]) { 07414 ast_mutex_unlock(&iaxsl[fr->callno]); 07415 return 1; 07416 } 07417 } else 07418 exists = 0; 07419 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 07420 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 07421 memset(&ied0, 0, sizeof(ied0)); 07422 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07423 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07424 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07425 if (!iaxs[fr->callno]) { 07426 ast_mutex_unlock(&iaxsl[fr->callno]); 07427 return 1; 07428 } 07429 if (authdebug) 07430 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); 07431 } else { 07432 /* Select an appropriate format */ 07433 07434 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07435 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07436 using_prefs = "reqonly"; 07437 } else { 07438 using_prefs = "disabled"; 07439 } 07440 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 07441 memset(&pref, 0, sizeof(pref)); 07442 strcpy(caller_pref_buf, "disabled"); 07443 strcpy(host_pref_buf, "disabled"); 07444 } else { 07445 using_prefs = "mine"; 07446 /* If the information elements are in here... use them */ 07447 if (ies.codec_prefs) 07448 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 07449 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07450 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 07451 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07452 pref = iaxs[fr->callno]->rprefs; 07453 using_prefs = "caller"; 07454 } else { 07455 pref = iaxs[fr->callno]->prefs; 07456 } 07457 } else 07458 pref = iaxs[fr->callno]->prefs; 07459 07460 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 07461 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 07462 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 07463 } 07464 if (!format) { 07465 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07466 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 07467 if (!format) { 07468 memset(&ied0, 0, sizeof(ied0)); 07469 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07470 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07471 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07472 if (!iaxs[fr->callno]) { 07473 ast_mutex_unlock(&iaxsl[fr->callno]); 07474 return 1; 07475 } 07476 if (authdebug) { 07477 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07478 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); 07479 else 07480 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); 07481 } 07482 } else { 07483 /* Pick one... */ 07484 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07485 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 07486 format = 0; 07487 } else { 07488 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07489 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 07490 memset(&pref, 0, sizeof(pref)); 07491 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07492 strcpy(caller_pref_buf,"disabled"); 07493 strcpy(host_pref_buf,"disabled"); 07494 } else { 07495 using_prefs = "mine"; 07496 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07497 /* Do the opposite of what we tried above. */ 07498 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07499 pref = iaxs[fr->callno]->prefs; 07500 } else { 07501 pref = iaxs[fr->callno]->rprefs; 07502 using_prefs = "caller"; 07503 } 07504 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 07505 07506 } else /* if no codec_prefs IE do it the old way */ 07507 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07508 } 07509 } 07510 07511 if (!format) { 07512 memset(&ied0, 0, sizeof(ied0)); 07513 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07514 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07515 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07516 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07517 if (!iaxs[fr->callno]) { 07518 ast_mutex_unlock(&iaxsl[fr->callno]); 07519 return 1; 07520 } 07521 if (authdebug) 07522 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); 07523 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07524 break; 07525 } 07526 } 07527 } 07528 if (format) { 07529 /* No authentication required, let them in */ 07530 memset(&ied1, 0, sizeof(ied1)); 07531 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 07532 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 07533 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 07534 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07535 if (option_verbose > 2) 07536 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" 07537 "%srequested format = %s,\n" 07538 "%srequested prefs = %s,\n" 07539 "%sactual format = %s,\n" 07540 "%shost prefs = %s,\n" 07541 "%spriority = %s\n", 07542 ast_inet_ntoa(sin.sin_addr), 07543 VERBOSE_PREFIX_4, 07544 ast_getformatname(iaxs[fr->callno]->peerformat), 07545 VERBOSE_PREFIX_4, 07546 caller_pref_buf, 07547 VERBOSE_PREFIX_4, 07548 ast_getformatname(format), 07549 VERBOSE_PREFIX_4, 07550 host_pref_buf, 07551 VERBOSE_PREFIX_4, 07552 using_prefs); 07553 07554 iaxs[fr->callno]->chosenformat = format; 07555 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07556 } else { 07557 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07558 /* If this is a TBD call, we're ready but now what... */ 07559 if (option_verbose > 2) 07560 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 07561 } 07562 } 07563 } 07564 break; 07565 } 07566 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 07567 merge_encryption(iaxs[fr->callno],ies.encmethods); 07568 else 07569 iaxs[fr->callno]->encmethods = 0; 07570 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 07571 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 07572 if (!iaxs[fr->callno]) { 07573 ast_mutex_unlock(&iaxsl[fr->callno]); 07574 return 1; 07575 } 07576 break; 07577 case IAX_COMMAND_DPREQ: 07578 /* Request status in the dialplan */ 07579 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 07580 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 07581 if (iaxcompat) { 07582 /* Spawn a thread for the lookup */ 07583 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 07584 } else { 07585 /* Just look it up */ 07586 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 07587 } 07588 } 07589 break; 07590 case IAX_COMMAND_HANGUP: 07591 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07592 if (option_debug) 07593 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno); 07594 /* Set hangup cause according to remote */ 07595 if (ies.causecode && iaxs[fr->callno]->owner) 07596 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07597 /* Send ack immediately, before we destroy */ 07598 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07599 iax2_destroy(fr->callno); 07600 break; 07601 case IAX_COMMAND_REJECT: 07602 /* Set hangup cause according to remote */ 07603 if (ies.causecode && iaxs[fr->callno]->owner) 07604 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07605 07606 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07607 if (iaxs[fr->callno]->owner && authdebug) 07608 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 07609 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 07610 ies.cause ? ies.cause : "<Unknown>"); 07611 if (option_debug) 07612 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", 07613 fr->callno); 07614 } 07615 /* Send ack immediately, before we destroy */ 07616 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 07617 fr->ts, NULL, 0, fr->iseqno); 07618 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) 07619 iaxs[fr->callno]->error = EPERM; 07620 iax2_destroy(fr->callno); 07621 break; 07622 case IAX_COMMAND_TRANSFER: 07623 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && ies.called_number) { 07624 /* Set BLINDTRANSFER channel variables */ 07625 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", ast_bridged_channel(iaxs[fr->callno]->owner)->name); 07626 pbx_builtin_setvar_helper(ast_bridged_channel(iaxs[fr->callno]->owner), "BLINDTRANSFER", iaxs[fr->callno]->owner->name); 07627 if (!strcmp(ies.called_number, ast_parking_ext())) { 07628 if (iax_park(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->owner)) { 07629 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name); 07630 } else if (ast_bridged_channel(iaxs[fr->callno]->owner)) 07631 ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name); 07632 } else { 07633 if (ast_async_goto(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->context, ies.called_number, 1)) 07634 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 07635 ies.called_number, iaxs[fr->callno]->context); 07636 else 07637 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 07638 ies.called_number, iaxs[fr->callno]->context); 07639 } 07640 } else 07641 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno); 07642 break; 07643 case IAX_COMMAND_ACCEPT: 07644 /* Ignore if call is already up or needs authentication or is a TBD */ 07645 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 07646 break; 07647 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07648 /* Send ack immediately, before we destroy */ 07649 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07650 iax2_destroy(fr->callno); 07651 break; 07652 } 07653 if (ies.format) { 07654 iaxs[fr->callno]->peerformat = ies.format; 07655 } else { 07656 if (iaxs[fr->callno]->owner) 07657 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 07658 else 07659 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 07660 } 07661 if (option_verbose > 2) 07662 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)); 07663 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 07664 memset(&ied0, 0, sizeof(ied0)); 07665 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07666 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07667 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07668 if (!iaxs[fr->callno]) { 07669 ast_mutex_unlock(&iaxsl[fr->callno]); 07670 return 1; 07671 } 07672 if (authdebug) 07673 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); 07674 } else { 07675 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07676 if (iaxs[fr->callno]->owner) { 07677 /* Switch us to use a compatible format */ 07678 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 07679 if (option_verbose > 2) 07680 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 07681 retryowner2: 07682 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07683 ast_mutex_unlock(&iaxsl[fr->callno]); 07684 usleep(1); 07685 ast_mutex_lock(&iaxsl[fr->callno]); 07686 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2; 07687 } 07688 07689 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 07690 /* Setup read/write formats properly. */ 07691 if (iaxs[fr->callno]->owner->writeformat) 07692 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 07693 if (iaxs[fr->callno]->owner->readformat) 07694 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07695 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07696 } 07697 } 07698 } 07699 if (iaxs[fr->callno]) { 07700 ast_mutex_lock(&dpcache_lock); 07701 dp = iaxs[fr->callno]->dpentries; 07702 while(dp) { 07703 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) { 07704 iax2_dprequest(dp, fr->callno); 07705 } 07706 dp = dp->peer; 07707 } 07708 ast_mutex_unlock(&dpcache_lock); 07709 } 07710 break; 07711 case IAX_COMMAND_POKE: 07712 /* Send back a pong packet with the original timestamp */ 07713 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 07714 if (!iaxs[fr->callno]) { 07715 ast_mutex_unlock(&iaxsl[fr->callno]); 07716 return 1; 07717 } 07718 break; 07719 case IAX_COMMAND_PING: 07720 { 07721 struct iax_ie_data pingied; 07722 construct_rr(iaxs[fr->callno], &pingied); 07723 /* Send back a pong packet with the original timestamp */ 07724 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 07725 } 07726 break; 07727 case IAX_COMMAND_PONG: 07728 /* Calculate ping time */ 07729 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 07730 /* save RR info */ 07731 save_rr(fr, &ies); 07732 07733 if (iaxs[fr->callno]->peerpoke) { 07734 peer = iaxs[fr->callno]->peerpoke; 07735 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 07736 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 07737 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 07738 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07739 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07740 } 07741 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 07742 if (iaxs[fr->callno]->pingtime > peer->maxms) { 07743 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 07744 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07745 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07746 } 07747 } 07748 peer->lastms = iaxs[fr->callno]->pingtime; 07749 if (peer->smoothing && (peer->lastms > -1)) 07750 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 07751 else if (peer->smoothing && peer->lastms < 0) 07752 peer->historicms = (0 + peer->historicms) / 2; 07753 else 07754 peer->historicms = iaxs[fr->callno]->pingtime; 07755 07756 /* Remove scheduled iax2_poke_noanswer */ 07757 if (peer->pokeexpire > -1) { 07758 if (!ast_sched_del(sched, peer->pokeexpire)) { 07759 peer_unref(peer); 07760 peer->pokeexpire = -1; 07761 } 07762 } 07763 /* Schedule the next cycle */ 07764 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 07765 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 07766 else 07767 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 07768 if (peer->pokeexpire == -1) 07769 peer_unref(peer); 07770 /* and finally send the ack */ 07771 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07772 /* And wrap up the qualify call */ 07773 iax2_destroy(fr->callno); 07774 peer->callno = 0; 07775 if (option_debug) 07776 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 07777 } 07778 break; 07779 case IAX_COMMAND_LAGRQ: 07780 case IAX_COMMAND_LAGRP: 07781 f.src = "LAGRQ"; 07782 f.mallocd = 0; 07783 f.offset = 0; 07784 f.samples = 0; 07785 iax_frame_wrap(fr, &f); 07786 if(f.subclass == IAX_COMMAND_LAGRQ) { 07787 /* Received a LAGRQ - echo back a LAGRP */ 07788 fr->af.subclass = IAX_COMMAND_LAGRP; 07789 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 07790 } else { 07791 /* Received LAGRP in response to our LAGRQ */ 07792 unsigned int ts; 07793 /* This is a reply we've been given, actually measure the difference */ 07794 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 07795 iaxs[fr->callno]->lag = ts - fr->ts; 07796 if (option_debug && iaxdebug) 07797 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", 07798 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 07799 } 07800 break; 07801 case IAX_COMMAND_AUTHREQ: 07802 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07803 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>"); 07804 break; 07805 } 07806 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 07807 ast_log(LOG_WARNING, 07808 "I don't know how to authenticate %s to %s\n", 07809 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 07810 } 07811 if (!iaxs[fr->callno]) { 07812 ast_mutex_unlock(&iaxsl[fr->callno]); 07813 return 1; 07814 } 07815 break; 07816 case IAX_COMMAND_AUTHREP: 07817 /* For security, always ack immediately */ 07818 if (delayreject) 07819 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07820 /* Ignore once we've started */ 07821 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07822 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>"); 07823 break; 07824 } 07825 if (authenticate_verify(iaxs[fr->callno], &ies)) { 07826 if (authdebug) 07827 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); 07828 memset(&ied0, 0, sizeof(ied0)); 07829 auth_fail(fr->callno, IAX_COMMAND_REJECT); 07830 break; 07831 } 07832 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 07833 /* This might re-enter the IAX code and need the lock */ 07834 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 07835 } else 07836 exists = 0; 07837 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 07838 if (authdebug) 07839 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); 07840 memset(&ied0, 0, sizeof(ied0)); 07841 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07842 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07843 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07844 if (!iaxs[fr->callno]) { 07845 ast_mutex_unlock(&iaxsl[fr->callno]); 07846 return 1; 07847 } 07848 } else { 07849 /* Select an appropriate format */ 07850 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07851 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07852 using_prefs = "reqonly"; 07853 } else { 07854 using_prefs = "disabled"; 07855 } 07856 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 07857 memset(&pref, 0, sizeof(pref)); 07858 strcpy(caller_pref_buf, "disabled"); 07859 strcpy(host_pref_buf, "disabled"); 07860 } else { 07861 using_prefs = "mine"; 07862 if (ies.codec_prefs) 07863 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 07864 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07865 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07866 pref = iaxs[fr->callno]->rprefs; 07867 using_prefs = "caller"; 07868 } else { 07869 pref = iaxs[fr->callno]->prefs; 07870 } 07871 } else /* if no codec_prefs IE do it the old way */ 07872 pref = iaxs[fr->callno]->prefs; 07873 07874 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 07875 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 07876 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 07877 } 07878 if (!format) { 07879 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07880 if (option_debug) 07881 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); 07882 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 07883 } 07884 if (!format) { 07885 if (authdebug) { 07886 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07887 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); 07888 else 07889 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); 07890 } 07891 memset(&ied0, 0, sizeof(ied0)); 07892 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07893 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07894 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07895 if (!iaxs[fr->callno]) { 07896 ast_mutex_unlock(&iaxsl[fr->callno]); 07897 return 1; 07898 } 07899 } else { 07900 /* Pick one... */ 07901 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07902 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 07903 format = 0; 07904 } else { 07905 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07906 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 07907 memset(&pref, 0, sizeof(pref)); 07908 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 07909 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07910 strcpy(caller_pref_buf,"disabled"); 07911 strcpy(host_pref_buf,"disabled"); 07912 } else { 07913 using_prefs = "mine"; 07914 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07915 /* Do the opposite of what we tried above. */ 07916 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07917 pref = iaxs[fr->callno]->prefs; 07918 } else { 07919 pref = iaxs[fr->callno]->rprefs; 07920 using_prefs = "caller"; 07921 } 07922 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 07923 } else /* if no codec_prefs IE do it the old way */ 07924 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07925 } 07926 } 07927 if (!format) { 07928 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07929 if (authdebug) { 07930 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07931 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); 07932 else 07933 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); 07934 } 07935 memset(&ied0, 0, sizeof(ied0)); 07936 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07937 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07938 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07939 if (!iaxs[fr->callno]) { 07940 ast_mutex_unlock(&iaxsl[fr->callno]); 07941 return 1; 07942 } 07943 } 07944 } 07945 } 07946 if (format) { 07947 /* Authentication received */ 07948 memset(&ied1, 0, sizeof(ied1)); 07949 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 07950 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 07951 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 07952 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07953 if (option_verbose > 2) 07954 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" 07955 "%srequested format = %s,\n" 07956 "%srequested prefs = %s,\n" 07957 "%sactual format = %s,\n" 07958 "%shost prefs = %s,\n" 07959 "%spriority = %s\n", 07960 ast_inet_ntoa(sin.sin_addr), 07961 VERBOSE_PREFIX_4, 07962 ast_getformatname(iaxs[fr->callno]->peerformat), 07963 VERBOSE_PREFIX_4, 07964 caller_pref_buf, 07965 VERBOSE_PREFIX_4, 07966 ast_getformatname(format), 07967 VERBOSE_PREFIX_4, 07968 host_pref_buf, 07969 VERBOSE_PREFIX_4, 07970 using_prefs); 07971 07972 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07973 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 07974 iax2_destroy(fr->callno); 07975 } else { 07976 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07977 /* If this is a TBD call, we're ready but now what... */ 07978 if (option_verbose > 2) 07979 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 07980 } 07981 } 07982 } 07983 break; 07984 case IAX_COMMAND_DIAL: 07985 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 07986 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07987 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 07988 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 07989 if (authdebug) 07990 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); 07991 memset(&ied0, 0, sizeof(ied0)); 07992 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07993 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07994 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07995 if (!iaxs[fr->callno]) { 07996 ast_mutex_unlock(&iaxsl[fr->callno]); 07997 return 1; 07998 } 07999 } else { 08000 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08001 if (option_verbose > 2) 08002 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat); 08003 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08004 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 08005 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) 08006 iax2_destroy(fr->callno); 08007 } 08008 } 08009 break; 08010 case IAX_COMMAND_INVAL: 08011 iaxs[fr->callno]->error = ENOTCONN; 08012 if (option_debug) 08013 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno); 08014 iax2_destroy(fr->callno); 08015 if (option_debug) 08016 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno); 08017 break; 08018 case IAX_COMMAND_VNAK: 08019 if (option_debug) 08020 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); 08021 /* Force retransmission */ 08022 vnak_retransmit(fr->callno, fr->iseqno); 08023 break; 08024 case IAX_COMMAND_REGREQ: 08025 case IAX_COMMAND_REGREL: 08026 /* For security, always ack immediately */ 08027 if (delayreject) 08028 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08029 if (register_verify(fr->callno, &sin, &ies)) { 08030 if (!iaxs[fr->callno]) { 08031 ast_mutex_unlock(&iaxsl[fr->callno]); 08032 return 1; 08033 } 08034 /* Send delayed failure */ 08035 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 08036 break; 08037 } 08038 if (!iaxs[fr->callno]) { 08039 ast_mutex_unlock(&iaxsl[fr->callno]); 08040 return 1; 08041 } 08042 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 08043 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) { 08044 if (f.subclass == IAX_COMMAND_REGREL) 08045 memset(&sin, 0, sizeof(sin)); 08046 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) 08047 ast_log(LOG_WARNING, "Registry error\n"); 08048 if (!iaxs[fr->callno]) { 08049 ast_mutex_unlock(&iaxsl[fr->callno]); 08050 return 1; 08051 } 08052 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 08053 ast_mutex_unlock(&iaxsl[fr->callno]); 08054 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 08055 ast_mutex_lock(&iaxsl[fr->callno]); 08056 if (!iaxs[fr->callno]) { 08057 ast_mutex_unlock(&iaxsl[fr->callno]); 08058 return 1; 08059 } 08060 } 08061 break; 08062 } 08063 registry_authrequest(fr->callno); 08064 if (!iaxs[fr->callno]) { 08065 ast_mutex_unlock(&iaxsl[fr->callno]); 08066 return 1; 08067 } 08068 break; 08069 case IAX_COMMAND_REGACK: 08070 if (iax2_ack_registry(&ies, &sin, fr->callno)) 08071 ast_log(LOG_WARNING, "Registration failure\n"); 08072 /* Send ack immediately, before we destroy */ 08073 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08074 iax2_destroy(fr->callno); 08075 break; 08076 case IAX_COMMAND_REGREJ: 08077 if (iaxs[fr->callno]->reg) { 08078 if (authdebug) { 08079 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)); 08080 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>"); 08081 } 08082 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 08083 } 08084 /* Send ack immediately, before we destroy */ 08085 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08086 iax2_destroy(fr->callno); 08087 break; 08088 case IAX_COMMAND_REGAUTH: 08089 /* Authentication request */ 08090 if (registry_rerequest(&ies, fr->callno, &sin)) { 08091 memset(&ied0, 0, sizeof(ied0)); 08092 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 08093 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 08094 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08095 if (!iaxs[fr->callno]) { 08096 ast_mutex_unlock(&iaxsl[fr->callno]); 08097 return 1; 08098 } 08099 } 08100 break; 08101 case IAX_COMMAND_TXREJ: 08102 iaxs[fr->callno]->transferring = 0; 08103 if (option_verbose > 2) 08104 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 08105 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 08106 if (iaxs[fr->callno]->bridgecallno) { 08107 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 08108 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 08109 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 08110 } 08111 } 08112 break; 08113 case IAX_COMMAND_TXREADY: 08114 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 08115 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 08116 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 08117 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 08118 else 08119 iaxs[fr->callno]->transferring = TRANSFER_READY; 08120 if (option_verbose > 2) 08121 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 08122 if (iaxs[fr->callno]->bridgecallno) { 08123 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 08124 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 08125 /* They're both ready, now release them. */ 08126 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 08127 if (option_verbose > 2) 08128 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 08129 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 08130 08131 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 08132 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 08133 08134 memset(&ied0, 0, sizeof(ied0)); 08135 memset(&ied1, 0, sizeof(ied1)); 08136 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 08137 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 08138 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 08139 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 08140 } else { 08141 if (option_verbose > 2) 08142 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 08143 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 08144 08145 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 08146 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 08147 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 08148 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 08149 08150 /* Stop doing lag & ping requests */ 08151 stop_stuff(fr->callno); 08152 stop_stuff(iaxs[fr->callno]->bridgecallno); 08153 08154 memset(&ied0, 0, sizeof(ied0)); 08155 memset(&ied1, 0, sizeof(ied1)); 08156 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 08157 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 08158 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 08159 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 08160 } 08161 08162 } 08163 } 08164 } 08165 break; 08166 case IAX_COMMAND_TXREQ: 08167 try_transfer(iaxs[fr->callno], &ies); 08168 break; 08169 case IAX_COMMAND_TXCNT: 08170 if (iaxs[fr->callno]->transferring) 08171 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 08172 break; 08173 case IAX_COMMAND_TXREL: 08174 /* Send ack immediately, rather than waiting until we've changed addresses */ 08175 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08176 complete_transfer(fr->callno, &ies); 08177 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 08178 break; 08179 case IAX_COMMAND_TXMEDIA: 08180 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 08181 AST_LIST_LOCK(&iaxq.queue); 08182 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 08183 /* Cancel any outstanding frames and start anew */ 08184 if ((fr->callno == cur->callno) && (cur->transfer)) { 08185 cur->retries = -1; 08186 } 08187 } 08188 AST_LIST_UNLOCK(&iaxq.queue); 08189 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 08190 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 08191 } 08192 break; 08193 case IAX_COMMAND_DPREP: 08194 complete_dpreply(iaxs[fr->callno], &ies); 08195 break; 08196 case IAX_COMMAND_UNSUPPORT: 08197 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 08198 break; 08199 case IAX_COMMAND_FWDOWNL: 08200 /* Firmware download */ 08201 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 08202 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 08203 break; 08204 } 08205 memset(&ied0, 0, sizeof(ied0)); 08206 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 08207 if (res < 0) 08208 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08209 else if (res > 0) 08210 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08211 else 08212 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08213 if (!iaxs[fr->callno]) { 08214 ast_mutex_unlock(&iaxsl[fr->callno]); 08215 return 1; 08216 } 08217 break; 08218 default: 08219 if (option_debug) 08220 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); 08221 memset(&ied0, 0, sizeof(ied0)); 08222 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 08223 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 08224 } 08225 /* Don't actually pass these frames along */ 08226 if ((f.subclass != IAX_COMMAND_ACK) && 08227 (f.subclass != IAX_COMMAND_TXCNT) && 08228 (f.subclass != IAX_COMMAND_TXACC) && 08229 (f.subclass != IAX_COMMAND_INVAL) && 08230 (f.subclass != IAX_COMMAND_VNAK)) { 08231 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08232 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08233 } 08234 ast_mutex_unlock(&iaxsl[fr->callno]); 08235 return 1; 08236 } 08237 /* Unless this is an ACK or INVAL frame, ack it */ 08238 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08239 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08240 } else if (minivid) { 08241 f.frametype = AST_FRAME_VIDEO; 08242 if (iaxs[fr->callno]->videoformat > 0) 08243 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 08244 else { 08245 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n "); 08246 iax2_vnak(fr->callno); 08247 ast_mutex_unlock(&iaxsl[fr->callno]); 08248 return 1; 08249 } 08250 f.datalen = res - sizeof(*vh); 08251 if (f.datalen) 08252 f.data = thread->buf + sizeof(*vh); 08253 else 08254 f.data = NULL; 08255 #ifdef IAXTESTS 08256 if (test_resync) { 08257 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 08258 } else 08259 #endif /* IAXTESTS */ 08260 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 08261 } else { 08262 /* A mini frame */ 08263 f.frametype = AST_FRAME_VOICE; 08264 if (iaxs[fr->callno]->voiceformat > 0) 08265 f.subclass = iaxs[fr->callno]->voiceformat; 08266 else { 08267 if (option_debug) 08268 ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n"); 08269 iax2_vnak(fr->callno); 08270 ast_mutex_unlock(&iaxsl[fr->callno]); 08271 return 1; 08272 } 08273 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 08274 if (f.datalen < 0) { 08275 ast_log(LOG_WARNING, "Datalen < 0?\n"); 08276 ast_mutex_unlock(&iaxsl[fr->callno]); 08277 return 1; 08278 } 08279 if (f.datalen) 08280 f.data = thread->buf + sizeof(*mh); 08281 else 08282 f.data = NULL; 08283 #ifdef IAXTESTS 08284 if (test_resync) { 08285 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 08286 } else 08287 #endif /* IAXTESTS */ 08288 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 08289 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 08290 } 08291 /* Don't pass any packets until we're started */ 08292 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 08293 ast_mutex_unlock(&iaxsl[fr->callno]); 08294 return 1; 08295 } 08296 /* Common things */ 08297 f.src = "IAX2"; 08298 f.mallocd = 0; 08299 f.offset = 0; 08300 f.len = 0; 08301 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 08302 f.samples = ast_codec_get_samples(&f); 08303 /* We need to byteswap incoming slinear samples from network byte order */ 08304 if (f.subclass == AST_FORMAT_SLINEAR) 08305 ast_frame_byteswap_be(&f); 08306 } else 08307 f.samples = 0; 08308 iax_frame_wrap(fr, &f); 08309 08310 /* If this is our most recent packet, use it as our basis for timestamping */ 08311 if (iaxs[fr->callno]->last < fr->ts) { 08312 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 08313 fr->outoforder = 0; 08314 } else { 08315 if (option_debug && iaxdebug) 08316 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); 08317 fr->outoforder = -1; 08318 } 08319 duped_fr = iaxfrdup2(fr); 08320 if (duped_fr) { 08321 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 08322 } 08323 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08324 iaxs[fr->callno]->last = fr->ts; 08325 #if 1 08326 if (option_debug && iaxdebug) 08327 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 08328 #endif 08329 } 08330 08331 /* Always run again */ 08332 ast_mutex_unlock(&iaxsl[fr->callno]); 08333 return 1; 08334 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6731 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_random(), iax2_registry::callno, ast_iax2_full_hdr::csub, defer_full_frame(), errno, iax2_thread::ffinfo, find_idle_thread(), handle_error(), IAX_FLAG_FULL, IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, inaddrcmp(), len, LOG_NOTICE, LOG_WARNING, ast_iax2_full_hdr::scallno, signal_condition(), t, thread, and ast_iax2_full_hdr::type.
Referenced by network_thread(), peer_set_srcaddr(), and set_config().
06732 { 06733 struct iax2_thread *thread; 06734 socklen_t len; 06735 time_t t; 06736 static time_t last_errtime = 0; 06737 struct ast_iax2_full_hdr *fh; 06738 06739 if (!(thread = find_idle_thread())) { 06740 time(&t); 06741 if (t != last_errtime) 06742 ast_log(LOG_NOTICE, "Out of idle IAX2 threads for I/O, pausing!\n"); 06743 last_errtime = t; 06744 usleep(1); 06745 return 1; 06746 } 06747 06748 len = sizeof(thread->iosin); 06749 thread->iofd = fd; 06750 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 06751 thread->buf_size = sizeof(thread->readbuf); 06752 thread->buf = thread->readbuf; 06753 if (thread->buf_len < 0) { 06754 if (errno != ECONNREFUSED && errno != EAGAIN) 06755 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 06756 handle_error(); 06757 thread->iostate = IAX_IOSTATE_IDLE; 06758 signal_condition(&thread->lock, &thread->cond); 06759 return 1; 06760 } 06761 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 06762 thread->iostate = IAX_IOSTATE_IDLE; 06763 signal_condition(&thread->lock, &thread->cond); 06764 return 1; 06765 } 06766 06767 /* Determine if this frame is a full frame; if so, and any thread is currently 06768 processing a full frame for the same callno from this peer, then drop this 06769 frame (and the peer will retransmit it) */ 06770 fh = (struct ast_iax2_full_hdr *) thread->buf; 06771 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06772 struct iax2_thread *cur = NULL; 06773 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 06774 06775 AST_LIST_LOCK(&active_list); 06776 AST_LIST_TRAVERSE(&active_list, cur, list) { 06777 if ((cur->ffinfo.callno == callno) && 06778 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 06779 break; 06780 } 06781 if (cur) { 06782 /* we found another thread processing a full frame for this call, 06783 so queue it up for processing later. */ 06784 defer_full_frame(thread, cur); 06785 AST_LIST_UNLOCK(&active_list); 06786 thread->iostate = IAX_IOSTATE_IDLE; 06787 signal_condition(&thread->lock, &thread->cond); 06788 return 1; 06789 } else { 06790 /* this thread is going to process this frame, so mark it */ 06791 thread->ffinfo.callno = callno; 06792 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 06793 thread->ffinfo.type = fh->type; 06794 thread->ffinfo.csub = fh->csub; 06795 } 06796 AST_LIST_UNLOCK(&active_list); 06797 } 06798 06799 /* Mark as ready and send on its way */ 06800 thread->iostate = IAX_IOSTATE_READY; 06801 #ifdef DEBUG_SCHED_MULTITHREAD 06802 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 06803 #endif 06804 signal_condition(&thread->lock, &thread->cond); 06805 06806 return 1; 06807 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 6518 of file chan_iax2.c.
References ast_calloc, ast_log(), ast_pthread_create, ast_strdup, dpreq_data::callednum, dpreq_data::callerid, dpreq_data::callno, dpreq_data::context, dp_lookup_thread(), and LOG_WARNING.
Referenced by socket_process().
06519 { 06520 pthread_t newthread; 06521 struct dpreq_data *dpr; 06522 pthread_attr_t attr; 06523 06524 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 06525 return; 06526 06527 pthread_attr_init(&attr); 06528 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06529 06530 dpr->callno = callno; 06531 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 06532 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 06533 if (callerid) 06534 dpr->callerid = ast_strdup(callerid); 06535 if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) { 06536 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 06537 } 06538 06539 pthread_attr_destroy(&attr); 06540 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 8933 of file chan_iax2.c.
References ast_calloc, ast_cond_init(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_init(), ast_pthread_create, ast_pthread_create_background, ast_verbose(), free, iax2_process_thread(), IAX_TYPE_POOL, iaxthreadcount, LOG_WARNING, network_thread(), option_verbose, sched_thread(), thread, and VERBOSE_PREFIX_2.
Referenced by load_module().
08934 { 08935 pthread_attr_t attr; 08936 int threadcount = 0; 08937 int x; 08938 for (x = 0; x < iaxthreadcount; x++) { 08939 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread)); 08940 if (thread) { 08941 thread->type = IAX_TYPE_POOL; 08942 thread->threadnum = ++threadcount; 08943 ast_mutex_init(&thread->lock); 08944 ast_cond_init(&thread->cond, NULL); 08945 pthread_attr_init(&attr); 08946 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 08947 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 08948 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 08949 free(thread); 08950 thread = NULL; 08951 } 08952 AST_LIST_LOCK(&idle_list); 08953 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 08954 AST_LIST_UNLOCK(&idle_list); 08955 } 08956 } 08957 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL); 08958 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 08959 if (option_verbose > 1) 08960 ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount); 08961 return 0; 08962 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 6203 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
06204 { 06205 iax2_destroy_helper(iaxs[callno]); 06206 }
static int timing_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6392 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_inet_ntoa(), AST_IO_PRI, ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), free, iax2_trunk_expired(), iax2_trunk_peer::lock, LOG_DEBUG, LOG_WARNING, MAX_TRUNKDATA, iax2_trunk_peer::next, option_debug, send_trunk(), tpeers, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.
Referenced by network_thread().
06393 { 06394 char buf[1024]; 06395 int res; 06396 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL; 06397 int processed = 0; 06398 int totalcalls = 0; 06399 #ifdef ZT_TIMERACK 06400 int x = 1; 06401 #endif 06402 struct timeval now; 06403 if (iaxtrunkdebug) 06404 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA); 06405 gettimeofday(&now, NULL); 06406 if (events & AST_IO_PRI) { 06407 #ifdef ZT_TIMERACK 06408 /* Great, this is a timing interface, just call the ioctl */ 06409 if (ioctl(fd, ZT_TIMERACK, &x)) 06410 ast_log(LOG_WARNING, "Unable to acknowledge zap timer\n"); 06411 res = 0; 06412 #endif 06413 } else { 06414 /* Read and ignore from the pseudo channel for timing */ 06415 res = read(fd, buf, sizeof(buf)); 06416 if (res < 1) { 06417 ast_log(LOG_WARNING, "Unable to read from timing fd\n"); 06418 return 1; 06419 } 06420 } 06421 /* For each peer that supports trunking... */ 06422 ast_mutex_lock(&tpeerlock); 06423 tpeer = tpeers; 06424 while(tpeer) { 06425 processed++; 06426 res = 0; 06427 ast_mutex_lock(&tpeer->lock); 06428 /* We can drop a single tpeer per pass. That makes all this logic 06429 substantially easier */ 06430 if (!drop && iax2_trunk_expired(tpeer, &now)) { 06431 /* Take it out of the list, but don't free it yet, because it 06432 could be in use */ 06433 if (prev) 06434 prev->next = tpeer->next; 06435 else 06436 tpeers = tpeer->next; 06437 drop = tpeer; 06438 } else { 06439 res = send_trunk(tpeer, &now); 06440 if (iaxtrunkdebug) 06441 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); 06442 } 06443 totalcalls += res; 06444 res = 0; 06445 ast_mutex_unlock(&tpeer->lock); 06446 prev = tpeer; 06447 tpeer = tpeer->next; 06448 } 06449 ast_mutex_unlock(&tpeerlock); 06450 if (drop) { 06451 ast_mutex_lock(&drop->lock); 06452 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 06453 because by the time they could get tpeerlock, we've already grabbed it */ 06454 if (option_debug) 06455 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 06456 free(drop->trunkdata); 06457 ast_mutex_unlock(&drop->lock); 06458 ast_mutex_destroy(&drop->lock); 06459 free(drop); 06460 06461 } 06462 if (iaxtrunkdebug) 06463 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 06464 iaxtrunkdebug =0; 06465 return 1; 06466 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 1868 of file chan_iax2.c.
References ast_log(), iax_frame::data, iax_frame::datalen, errno, handle_error(), LOG_DEBUG, and option_debug.
Referenced by send_trunk().
01869 { 01870 int res; 01871 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 01872 sizeof(*sin)); 01873 if (res < 0) { 01874 if (option_debug) 01875 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 01876 handle_error(); 01877 } else 01878 res = 0; 01879 return res; 01880 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 1556 of file chan_iax2.c.
References ast_calloc, ast_log(), ast_random(), ast_strlen_zero(), MD5Context::buf, ast_iax2_firmware_header::chksum, ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, iax_firmware::dead, ast_iax2_firmware_header::devname, errno, iax_firmware::fd, iax_firmware::fwh, IAX_FIRMWARE_MAGIC, last, len, LOG_WARNING, ast_iax2_firmware_header::magic, MD5Final(), MD5Init(), MD5Update(), iax_firmware::mmaplen, iax_firmware::next, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl.
Referenced by reload_firmware().
01557 { 01558 struct stat stbuf; 01559 struct iax_firmware *cur; 01560 int ifd; 01561 int fd; 01562 int res; 01563 01564 struct ast_iax2_firmware_header *fwh, fwh2; 01565 struct MD5Context md5; 01566 unsigned char sum[16]; 01567 unsigned char buf[1024]; 01568 int len, chunk; 01569 char *s2; 01570 char *last; 01571 s2 = alloca(strlen(s) + 100); 01572 if (!s2) { 01573 ast_log(LOG_WARNING, "Alloca failed!\n"); 01574 return -1; 01575 } 01576 last = strrchr(s, '/'); 01577 if (last) 01578 last++; 01579 else 01580 last = s; 01581 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 01582 res = stat(s, &stbuf); 01583 if (res < 0) { 01584 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 01585 return -1; 01586 } 01587 /* Make sure it's not a directory */ 01588 if (S_ISDIR(stbuf.st_mode)) 01589 return -1; 01590 ifd = open(s, O_RDONLY); 01591 if (ifd < 0) { 01592 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 01593 return -1; 01594 } 01595 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600); 01596 if (fd < 0) { 01597 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 01598 close(ifd); 01599 return -1; 01600 } 01601 /* Unlink our newly created file */ 01602 unlink(s2); 01603 01604 /* Now copy the firmware into it */ 01605 len = stbuf.st_size; 01606 while(len) { 01607 chunk = len; 01608 if (chunk > sizeof(buf)) 01609 chunk = sizeof(buf); 01610 res = read(ifd, buf, chunk); 01611 if (res != chunk) { 01612 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01613 close(ifd); 01614 close(fd); 01615 return -1; 01616 } 01617 res = write(fd, buf, chunk); 01618 if (res != chunk) { 01619 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01620 close(ifd); 01621 close(fd); 01622 return -1; 01623 } 01624 len -= chunk; 01625 } 01626 close(ifd); 01627 /* Return to the beginning */ 01628 lseek(fd, 0, SEEK_SET); 01629 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 01630 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 01631 close(fd); 01632 return -1; 01633 } 01634 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 01635 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 01636 close(fd); 01637 return -1; 01638 } 01639 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 01640 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 01641 close(fd); 01642 return -1; 01643 } 01644 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 01645 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 01646 close(fd); 01647 return -1; 01648 } 01649 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 01650 if (fwh == (void *) -1) { 01651 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 01652 close(fd); 01653 return -1; 01654 } 01655 MD5Init(&md5); 01656 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 01657 MD5Final(sum, &md5); 01658 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 01659 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 01660 munmap((void*)fwh, stbuf.st_size); 01661 close(fd); 01662 return -1; 01663 } 01664 cur = waresl.wares; 01665 while(cur) { 01666 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 01667 /* Found a candidate */ 01668 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 01669 /* The version we have on loaded is older, load this one instead */ 01670 break; 01671 /* This version is no newer than what we have. Don't worry about it. 01672 We'll consider it a proper load anyhow though */ 01673 munmap((void*)fwh, stbuf.st_size); 01674 close(fd); 01675 return 0; 01676 } 01677 cur = cur->next; 01678 } 01679 if (!cur) { 01680 /* Allocate a new one and link it */ 01681 if ((cur = ast_calloc(1, sizeof(*cur)))) { 01682 cur->fd = -1; 01683 cur->next = waresl.wares; 01684 waresl.wares = cur; 01685 } 01686 } 01687 if (cur) { 01688 if (cur->fwh) { 01689 munmap((void*)cur->fwh, cur->mmaplen); 01690 } 01691 if (cur->fd > -1) 01692 close(cur->fd); 01693 cur->fwh = fwh; 01694 cur->fd = fd; 01695 cur->mmaplen = stbuf.st_size; 01696 cur->dead = 0; 01697 } 01698 return 0; 01699 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5604 of file chan_iax2.c.
References iax_ies::apparent_addr, AST_FRAME_IAX, ast_log(), iax_ie_data::buf, iax_ies::callno, IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, LOG_WARNING, iax_ie_data::pos, send_command_transfer(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, chan_iax2_pvt::transfercallno, iax_ies::transferid, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.
Referenced by socket_process().
05605 { 05606 int newcall = 0; 05607 char newip[256]; 05608 struct iax_ie_data ied; 05609 struct sockaddr_in new; 05610 05611 05612 memset(&ied, 0, sizeof(ied)); 05613 if (ies->apparent_addr) 05614 bcopy(ies->apparent_addr, &new, sizeof(new)); 05615 if (ies->callno) 05616 newcall = ies->callno; 05617 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 05618 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05619 return -1; 05620 } 05621 pvt->transfercallno = newcall; 05622 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 05623 inet_aton(newip, &pvt->transfer.sin_addr); 05624 pvt->transfer.sin_family = AF_INET; 05625 pvt->transferring = TRANSFER_BEGIN; 05626 pvt->transferid = ies->transferid; 05627 if (ies->transferid) 05628 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 05629 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 05630 return 0; 05631 }
static int uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1059 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), and socket_process().
01060 { 01061 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01062 if (csub & IAX_FLAG_SC_LOG) { 01063 /* special case for 'compressed' -1 */ 01064 if (csub == 0xff) 01065 return -1; 01066 else 01067 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01068 } 01069 else 01070 return csub; 01071 }
static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 5871 of file chan_iax2.c.
References ao2_unlink(), ast_sched_del(), iax2_peer::expire, peer_unref(), peers, and iax2_peer::pokeexpire.
Referenced by __expire_registry(), build_peer(), and prune_peers().
05872 { 05873 if (peer->expire > -1) { 05874 if (!ast_sched_del(sched, peer->expire)) { 05875 peer->expire = -1; 05876 peer_unref(peer); 05877 } 05878 } 05879 05880 if (peer->pokeexpire > -1) { 05881 if (!ast_sched_del(sched, peer->pokeexpire)) { 05882 peer->pokeexpire = -1; 05883 peer_unref(peer); 05884 } 05885 } 05886 05887 ao2_unlink(peers, peer); 05888 }
static int unload_module | ( | void | ) | [static] |
Definition at line 10850 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), and iaxpeer_function.
10851 { 10852 ast_custom_function_unregister(&iaxpeer_function); 10853 return __unload_module(); 10854 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3369 of file chan_iax2.c.
References ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
03370 { 03371 ast_mutex_unlock(&iaxsl[callno1]); 03372 ast_mutex_unlock(&iaxsl[callno0]); 03373 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2410 of file chan_iax2.c.
References ast_log(), iax_frame::callno, iaxs, chan_iax2_pvt::last, LOG_DEBUG, option_debug, and iax_frame::ts.
Referenced by schedule_delivery().
02411 { 02412 int x; 02413 02414 if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) { 02415 x = fr->ts - iaxs[fr->callno]->last; 02416 if (x < -50000) { 02417 /* Sudden big jump backwards in timestamp: 02418 What likely happened here is that miniframe timestamp has circled but we haven't 02419 gotten the update from the main packet. We'll just pretend that we did, and 02420 update the timestamp appropriately. */ 02421 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF); 02422 if (option_debug && iaxdebug) 02423 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n"); 02424 } 02425 if (x > 50000) { 02426 /* Sudden apparent big jump forwards in timestamp: 02427 What's likely happened is this is an old miniframe belonging to the previous 02428 top-16-bit timestamp that has turned up out of order. 02429 Adjust the timestamp appropriately. */ 02430 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF); 02431 if (option_debug && iaxdebug) 02432 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n"); 02433 } 02434 } 02435 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2439 of file chan_iax2.c.
References ast_sched_del(), chan_iax2_pvt::callno, CALLNO_TO_PTR, get_from_jb(), iax2_sched_add(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, and chan_iax2_pvt::rxcore.
Referenced by __get_from_jb(), and schedule_delivery().
02440 { 02441 int when; 02442 02443 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 02444 02445 when = jb_next(pvt->jb) - when; 02446 02447 if(pvt->jbid > -1) ast_sched_del(sched, pvt->jbid); 02448 02449 if(when <= 0) { 02450 /* XXX should really just empty until when > 0.. */ 02451 when = 1; 02452 } 02453 02454 pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno)); 02455 }
static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 1279 of file chan_iax2.c.
References ast_log(), iaxs, LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by find_callno(), and make_trunk().
01280 { 01281 int max = 1; 01282 int x; 01283 /* XXX Prolly don't need locks here XXX */ 01284 for (x=1;x<TRUNK_CALL_START - 1; x++) { 01285 if (iaxs[x]) 01286 max = x + 1; 01287 } 01288 maxnontrunkcall = max; 01289 if (option_debug && iaxdebug) 01290 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max); 01291 }
static void update_max_trunk | ( | void | ) | [static] |
Definition at line 1265 of file chan_iax2.c.
References ast_log(), IAX_MAX_CALLS, iaxs, LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by iax2_destroy(), and make_trunk().
01266 { 01267 int max = TRUNK_CALL_START; 01268 int x; 01269 /* XXX Prolly don't need locks here XXX */ 01270 for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) { 01271 if (iaxs[x]) 01272 max = x + 1; 01273 } 01274 maxtrunkcall = max; 01275 if (option_debug && iaxdebug) 01276 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max); 01277 }
static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2047 of file chan_iax2.c.
References iax_frame::callno, iax_frame::data, iax_frame::dcallno, ast_iax2_full_hdr::dcallno, IAX_FLAG_RETRANS, iaxs, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, and iax_frame::iseqno.
Referenced by __attempt_transmit().
02048 { 02049 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 02050 struct ast_iax2_full_hdr *fh = f->data; 02051 /* Mark this as a retransmission */ 02052 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 02053 /* Update iseqno */ 02054 f->iseqno = iaxs[f->callno]->iseqno; 02055 fh->iseqno = f->iseqno; 02056 return 0; 02057 }
static int update_registry | ( | struct sockaddr_in * | sin, | |
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 5982 of file chan_iax2.c.
References iax2_peer::addr, ast_app_inboxcount(), ast_db_del(), ast_db_put(), ast_device_state_changed(), AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_verbose(), iax_ie_data::buf, EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), iax_check_version(), IAX_COMMAND_REGACK, IAX_HASCALLERID, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_DATETIME, IAX_IE_FIRMWAREVER, IAX_IE_MSGCOUNT, IAX_IE_REFRESH, IAX_IE_USERNAME, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, iaxs, iaxsl, inaddrcmp(), LOG_NOTICE, LOG_WARNING, manager_event(), option_verbose, peer_ref(), peer_unref(), iax_ie_data::pos, realtime_update_peer(), register_peer_exten(), send_command_final(), iax2_peer::sockfd, and VERBOSE_PREFIX_3.
Referenced by socket_process().
05983 { 05984 /* Called from IAX thread only, with proper iaxsl lock */ 05985 struct iax_ie_data ied; 05986 struct iax2_peer *p; 05987 int msgcount; 05988 char data[80]; 05989 int version; 05990 const char *peer_name; 05991 int res = -1; 05992 05993 memset(&ied, 0, sizeof(ied)); 05994 05995 peer_name = ast_strdupa(iaxs[callno]->peer); 05996 05997 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 05998 ast_mutex_unlock(&iaxsl[callno]); 05999 if (!(p = find_peer(peer_name, 1))) { 06000 ast_mutex_lock(&iaxsl[callno]); 06001 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 06002 return -1; 06003 } 06004 ast_mutex_lock(&iaxsl[callno]); 06005 if (!iaxs[callno]) 06006 goto return_unref; 06007 06008 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 06009 if (sin->sin_addr.s_addr) { 06010 time_t nowtime; 06011 time(&nowtime); 06012 realtime_update_peer(peer_name, sin, nowtime); 06013 } else { 06014 realtime_update_peer(peer_name, sin, 0); 06015 } 06016 } 06017 if (inaddrcmp(&p->addr, sin)) { 06018 if (iax2_regfunk) 06019 iax2_regfunk(p->name, 1); 06020 /* Stash the IP address from which they registered */ 06021 memcpy(&p->addr, sin, sizeof(p->addr)); 06022 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 06023 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 06024 ast_db_put("IAX/Registry", p->name, data); 06025 if (option_verbose > 2) 06026 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 06027 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 06028 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 06029 register_peer_exten(p, 1); 06030 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06031 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 06032 if (option_verbose > 2) 06033 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 06034 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 06035 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 06036 register_peer_exten(p, 0); 06037 ast_db_del("IAX/Registry", p->name); 06038 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06039 } 06040 /* Update the host */ 06041 /* Verify that the host is really there */ 06042 iax2_poke_peer(p, callno); 06043 } 06044 06045 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 06046 if (!iaxs[callno]) { 06047 res = 0; 06048 goto return_unref; 06049 } 06050 06051 /* Store socket fd */ 06052 p->sockfd = fd; 06053 /* Setup the expiry */ 06054 if (p->expire > -1) { 06055 if (!ast_sched_del(sched, p->expire)) { 06056 p->expire = -1; 06057 peer_unref(p); 06058 } 06059 } 06060 /* treat an unspecified refresh interval as the minimum */ 06061 if (!refresh) 06062 refresh = min_reg_expire; 06063 if (refresh > max_reg_expire) { 06064 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 06065 p->name, max_reg_expire, refresh); 06066 p->expiry = max_reg_expire; 06067 } else if (refresh < min_reg_expire) { 06068 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 06069 p->name, min_reg_expire, refresh); 06070 p->expiry = min_reg_expire; 06071 } else { 06072 p->expiry = refresh; 06073 } 06074 if (p->expiry && sin->sin_addr.s_addr) { 06075 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 06076 if (p->expire == -1) 06077 peer_unref(p); 06078 } 06079 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 06080 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 06081 if (sin->sin_addr.s_addr) { 06082 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 06083 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 06084 if (!ast_strlen_zero(p->mailbox)) { 06085 int new, old; 06086 ast_app_inboxcount(p->mailbox, &new, &old); 06087 if (new > 255) 06088 new = 255; 06089 if (old > 255) 06090 old = 255; 06091 msgcount = (old << 8) | new; 06092 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 06093 } 06094 if (ast_test_flag(p, IAX_HASCALLERID)) { 06095 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 06096 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 06097 } 06098 } 06099 version = iax_check_version(devtype); 06100 if (version) 06101 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 06102 06103 res = 0; 06104 06105 return_unref: 06106 peer_unref(p); 06107 06108 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 06109 }
static int user_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1106 of file chan_iax2.c.
Referenced by load_module().
01107 { 01108 struct iax2_user *user = obj, *user2 = arg; 01109 01110 return !strcasecmp(user->name, user2->name) ? CMP_MATCH : 0; 01111 }
static int user_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9575 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
09576 { 09577 struct iax2_user *user = obj; 09578 09579 ast_set_flag(user, IAX_DELME); 09580 09581 return 0; 09582 }
static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 9339 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().
09340 { 09341 struct iax2_user *user = obj; 09342 09343 ast_free_ha(user->ha); 09344 free_context(user->contexts); 09345 if(user->vars) { 09346 ast_variables_destroy(user->vars); 09347 user->vars = NULL; 09348 } 09349 ast_string_field_free_memory(user); 09350 }
static int user_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1096 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_module().
01097 { 01098 const struct iax2_user *user = obj; 01099 01100 return ast_str_hash(user->name); 01101 }
Definition at line 1145 of file chan_iax2.c.
References ao2_ref().
01146 { 01147 ao2_ref(user, +1); 01148 return user; 01149 }
Definition at line 1151 of file chan_iax2.c.
References ao2_ref().
Referenced by authenticate_request(), authenticate_verify(), build_user(), check_access(), iax2_destroy_helper(), iax2_show_users(), prune_users(), and set_config().
01152 { 01153 ao2_ref(user, -1); 01154 return NULL; 01155 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 6306 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax_frame::callno, f, iaxq, iaxs, iax_frame::oseqno, iax_frame::retries, and send_packet().
Referenced by socket_process().
06307 { 06308 struct iax_frame *f; 06309 06310 AST_LIST_LOCK(&iaxq.queue); 06311 AST_LIST_TRAVERSE(&iaxq.queue, f, list) { 06312 /* Send a copy immediately */ 06313 if ((f->callno == callno) && iaxs[f->callno] && 06314 ((unsigned char ) (f->oseqno - last) < 128) && 06315 (f->retries >= 0)) { 06316 send_packet(f); 06317 } 06318 } 06319 AST_LIST_UNLOCK(&iaxq.queue); 06320 }
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 224 of file chan_iax2.c.
Referenced by __oh323_new(), ast_cdr_setaccount(), ast_channel_alloc(), begin_dial(), check_user_full(), disa_exec(), features_call(), gtalk_new(), local_call(), sip_new(), tds_log(), wait_for_answer(), and zt_new().
int adsi = 0 [static] |
Definition at line 228 of file chan_iax2.c.
int amaflags = 0 [static] |
Definition at line 227 of file chan_iax2.c.
int authdebug = 1 [static] |
Definition at line 163 of file chan_iax2.c.
int autokill = 0 [static] |
Definition at line 164 of file chan_iax2.c.
struct ast_cli_entry cli_iax2[] [static] |
struct ast_cli_entry cli_iax2_jb_debug_deprecated [static] |
Initial value:
{ { "iax2", "jb", "debug", NULL }, iax2_do_jb_debug, NULL, NULL }
Definition at line 10650 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 10655 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 10665 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 10660 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 10645 of file chan_iax2.c.
char context[80] = "default" [static] |
Definition at line 148 of file chan_iax2.c.
char debug_jb_usage[] [static] |
Initial value:
"Usage: iax2 set debug jb\n" " Enables jitterbuffer debugging information\n"
Definition at line 10619 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 10611 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 10603 of file chan_iax2.c.
int defaultsockfd = -1 [static] |
Definition at line 181 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 229 of file chan_iax2.c.
struct iax2_dpcache * dpcache [static] |
Referenced by find_cache(), and iax2_show_cache().
int global_rtautoclear = 120 [static] |
Definition at line 283 of file chan_iax2.c.
struct ast_flags globalflags = { 0 } [static] |
Definition at line 232 of file chan_iax2.c.
Referenced by find_or_create(), find_user(), find_user_realtime(), forward_message(), load_config(), make_email_file(), notify_new_message(), populate_defaults(), sendmail(), and vm_execmain().
int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static] |
Definition at line 210 of file chan_iax2.c.
int iax2_encryption = 0 [static] |
Definition at line 230 of file chan_iax2.c.
enum { ... } iax2_flags |
int(* iax2_regfunk)(const char *username, int onoff) = NULL |
Referenced by __expire_registry(), reg_source_db(), and update_registry().
char iax2_reload_usage[] [static] |
Initial value:
"Usage: iax2 reload\n" " Reloads IAX configuration from iax.conf\n"
Definition at line 10561 of file chan_iax2.c.
enum { ... } iax2_state |
struct ast_switch iax2_switch [static] |
struct ast_channel_tech iax2_tech [static] |
Definition at line 852 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 10627 of file chan_iax2.c.
int iaxactivethreadcount = 0 [static] |
Definition at line 459 of file chan_iax2.c.
Referenced by __unload_module(), iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 165 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 212 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 168 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 170 of file chan_iax2.c.
int iaxdynamicthreadcount = 0 [static] |
Definition at line 458 of file chan_iax2.c.
Referenced by find_idle_thread(), and iax2_process_thread().
int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static] |
struct ast_iax2_queue iaxq [static] |
struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS] [static] |
Definition at line 816 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __do_deliver(), __get_from_jb(), __send_lagrq(), __send_ping(), __unload_module(), ast_cli_netstats(), ast_iax2_new(), auth_fail(), auth_reject(), authenticate_reply(), authenticate_request(), auto_hangup(), cache_get_callno_locked(), calc_timestamp(), check_access(), complete_transfer(), decrypt_frame(), delete_users(), dp_lookup(), find_cache(), find_callno(), fix_peerts(), function_iaxpeer(), iax2_ack_registry(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_dprequest(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_poke_peer(), iax2_predestroy(), iax2_prov_app(), iax2_provision(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), iax2_request(), iax2_show_channels(), iax2_start_transfer(), iax2_vnak(), iax2_write(), iax_showframe(), load_module(), make_trunk(), network_thread(), register_verify(), registry_authrequest(), registry_rerequest(), save_rr(), schedule_delivery(), send_command_final(), send_command_locked(), send_packet(), socket_process(), stop_stuff(), unwrap_timestamp(), update_max_nontrunk(), update_max_trunk(), update_packet(), update_registry(), and vnak_retransmit().
ast_mutex_t iaxsl[IAX_MAX_CALLS] [static] |
Definition at line 817 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __get_from_jb(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), __unload_module(), ast_cli_netstats(), ast_iax2_new(), auth_reject(), authenticate_reply(), auto_hangup(), cache_get_callno_locked(), delete_users(), dp_lookup(), find_cache(), find_callno(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_poke_peer(), iax2_provision(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), iax2_request(), iax2_show_channels(), iax2_write(), load_module(), lock_both(), make_trunk(), network_thread(), peer_destructor(), register_verify(), registry_authrequest(), send_command_locked(), socket_process(), unlock_both(), and update_registry().
int iaxthreadcount = DEFAULT_THREAD_COUNT [static] |
Definition at line 456 of file chan_iax2.c.
Referenced by iax2_show_threads(), set_config(), and start_network_thread().
int iaxtrunkdebug = 0 [static] |
Definition at line 214 of file chan_iax2.c.
struct io_context* io [static] |
Definition at line 207 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 156 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 150 of file chan_iax2.c.
int last_authmethod = 0 [static] |
Definition at line 166 of file chan_iax2.c.
struct timeval lastused[IAX_MAX_CALLS] [static] |
Definition at line 818 of file chan_iax2.c.
Referenced by find_callno(), iax2_destroy(), and make_trunk().
int max_reg_expire [static] |
Definition at line 175 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 154 of file chan_iax2.c.
int maxauthreq = 3 [static] |
Definition at line 153 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 159 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 161 of file chan_iax2.c.
int maxnontrunkcall = 1 [static] |
Definition at line 158 of file chan_iax2.c.
int maxtrunkcall = TRUNK_CALL_START [static] |
Definition at line 157 of file chan_iax2.c.
int min_reg_expire [static] |
Definition at line 174 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 225 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 226 of file chan_iax2.c.
Referenced by check_user_full(), create_addr_from_peer(), and sip_alloc().
struct ast_netsock_list* netsock [static] |
Definition at line 179 of file chan_iax2.c.
pthread_t netthreadid = AST_PTHREADT_NULL [static] |
Definition at line 234 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 10623 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 10615 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 10607 of file chan_iax2.c.
struct ast_netsock_list* outsock [static] |
used if sourceaddress specified and bindaddr == INADDR_ANY
Definition at line 180 of file chan_iax2.c.
char* papp = "IAX2Provision" [static] |
char* pdescrip [static] |
Initial value:
" IAX2Provision([template]): Provisions the calling IAXy (assuming\n" "the calling entity is in fact an IAXy) with the given template or\n" "default if one is not specified. Returns -1 on error or 0 on success.\n"
Definition at line 8588 of file chan_iax2.c.
Referenced by load_module().
struct ao2_container* peers [static] |
Definition at line 654 of file chan_iax2.c.
Referenced by __iax2_show_peers(), __unload_module(), abort_request(), authenticate_reply(), build_peer(), build_transactions(), cancel_request(), chanavail_exec(), check_request(), complete_iax2_show_peer(), complete_peer_helper(), delete_users(), destroy_trans(), discover_transactions(), dundi_flush(), dundi_ie_append_eid_appropriately(), dundi_lookup_thread(), dundi_precache_internal(), dundi_precache_thread(), dundi_query_thread(), dundi_rexmit(), dundi_show_entityid(), dundi_show_mappings(), dundi_show_peer(), dundi_show_peers(), dundi_show_requests(), dundi_show_trans(), find_peer(), handle_command_response(), iax2_getpeername(), iax2_getpeertrunk(), load_module(), mark_mappings(), mark_peers(), network_thread(), optimize_transactions(), poke_all_peers(), precache_transactions(), prune_mappings(), prune_peers(), query_transactions(), realtime_peer(), register_request(), set_config(), socket_read(), unlink_peer(), and unregister_request().
int ping_time = 21 [static] |
Definition at line 155 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 144 of file chan_iax2.c.
Referenced by ast_best_codec(), build_peer(), build_user(), check_access(), create_addr(), new_iax(), and set_config().
char prune_realtime_usage[] [static] |
Initial value:
"Usage: iax2 prune realtime [<peername>|all]\n" " Prunes object(s) from the cache\n"
Definition at line 10557 of file chan_iax2.c.
char* psyn = "Provision a calling IAXy with a given template" [static] |
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 151 of file chan_iax2.c.
int resyncthreshold = 1000 [static] |
Definition at line 160 of file chan_iax2.c.
struct sched_context* sched [static] |
Definition at line 208 of file chan_iax2.c.
ast_cond_t sched_cond [static] |
Definition at line 237 of file chan_iax2.c.
pthread_t schedthreadid = AST_PTHREADT_NULL [static] |
Definition at line 235 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 10549 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 10577 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 10595 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 10581 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 10553 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 10589 of file chan_iax2.c.
char show_prov_usage[] [static] |
Definition at line 10565 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 10599 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 10545 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 10585 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 10572 of file chan_iax2.c.
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 146 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 216 of file chan_iax2.c.
int timingfd = -1 [static] |
Definition at line 177 of file chan_iax2.c.
unsigned int tos = 0 [static] |
Definition at line 172 of file chan_iax2.c.
struct iax2_trunk_peer * tpeers [static] |
Referenced by find_tpeer(), and timing_read().
int trunkfreq = 20 [static] |
Definition at line 162 of file chan_iax2.c.
struct ao2_container* users [static] |
Definition at line 657 of file chan_iax2.c.
Referenced by __unload_module(), ast_get_manager_by_name_locked(), authenticate_request(), authenticate_verify(), build_user(), check_access(), complete_voicemail_show_users(), delete_users(), find_or_create(), find_user(), handle_showmanager(), handle_showmanagers(), handle_voicemail_show_users(), iax2_destroy_helper(), iax2_show_users(), init_manager(), load_config(), load_module(), prune_users(), realtime_user(), reset_user_pw(), and set_config().
struct ast_firmware_list waresl [static] |
Referenced by __unload_module(), iax2_show_firmware(), iax_check_version(), iax_firmware_append(), load_module(), reload_firmware(), and try_firmware().