#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 "iax2.h"
#include "iax2-parser.h"
#include "iax2-provision.h"
#include "jitterbuf.h"
Include dependency graph for chan_iax2.c:

Go to the source code of this file.
Data Structures | |
| struct | ast_firmware_list |
| struct | ast_iax2_queue |
| struct | chan_iax2_pvt |
| struct | create_addr_info |
| struct | dpreq_data |
| struct | iax2_context |
| struct | iax2_dpcache |
| struct | iax2_peer |
| struct | iax2_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_RETRY_TIME 10000 |
| #define | MAX_TIMESTAMP_SKEW 160 |
| #define | MAX_TRUNKDATA 640 * 200 |
| #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) } |
| enum | iax_reg_state { REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH } |
| enum | iax_transfer_state { TRANSFER_NONE = 0, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED, TRANSFER_PASSTHROUGH, TRANSFER_MBEGIN, TRANSFER_MREADY, TRANSFER_MRELEASED, TRANSFER_MPASSTHROUGH, TRANSFER_MEDIA, TRANSFER_MEDIAPASS } |
Functions | |
| static void | __attempt_transmit (void *data) |
| static void | __auth_reject (void *nothing) |
| static void | __auto_congest (void *nothing) |
| static void | __auto_hangup (void *nothing) |
| static int | __do_deliver (void *data) |
| static void | __expire_registry (void *data) |
| static void | __get_from_jb (void *p) |
| static void | __iax2_do_register_s (void *data) |
| static void | __iax2_poke_noanswer (void *data) |
| static void | __iax2_poke_peer_s (void *data) |
| static int | __iax2_show_peers (int manager, int fd, struct mansession *s, int argc, char *argv[]) |
| static int | __schedule_action (void(*func)(void *data), void *data, const char *funcname) |
| static int | __send_command (struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, int now, int transfer, int final) |
| static void | __send_lagrq (void *data) |
| static void | __send_ping (void *data) |
| static int | __unload_module (void) |
| static int | acf_iaxvar_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
| static int | acf_iaxvar_write (struct ast_channel *chan, char *cmd, char *varname, const char *value) |
| 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 (peers, iax2_peer) |
| static | AST_LIST_HEAD_STATIC (users, iax2_user) |
| static | AST_LIST_HEAD_STATIC (registrations, iax2_registry) |
| AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Inter Asterisk eXchange (Ver 2)",.load=load_module,.unload=unload_module,.reload=reload,) | |
| AST_MUTEX_DEFINE_STATIC (dpcache_lock) | |
| AST_MUTEX_DEFINE_STATIC (tpeerlock) | |
| AST_MUTEX_DEFINE_STATIC (sched_lock) | |
| static int | attempt_transmit (void *data) |
| static int | auth_fail (int callno, int failcode) |
| static int | auth_reject (void *data) |
| static int | authenticate (const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx) |
| static int | authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey) |
| static int | authenticate_request (struct chan_iax2_pvt *p) |
| static int | authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies) |
| static int | auto_congest (void *data) |
| static int | auto_hangup (void *data) |
| static struct iax2_context * | build_context (char *context) |
| static void | build_enc_keys (const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx) |
| static struct iax2_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
| Create peer structure based on configuration. | |
| static struct iax2_user * | build_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
| Create in-memory user structure from configuration. | |
| static int | cache_get_callno_locked (const char *data) |
| static unsigned int | calc_rxstamp (struct chan_iax2_pvt *p, unsigned int offset) |
| static unsigned int | calc_timestamp (struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f) |
| static unsigned int | calc_txpeerstamp (struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv) |
| static int | check_access (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
| static int | check_provisioning (struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver) |
| static int | check_srcaddr (struct sockaddr *sa, socklen_t salen) |
| Check if address can be used as packet source. | |
| static int | complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
| static char * | complete_iax2_show_peer (const char *line, const char *word, int pos, int state) |
| static int | complete_transfer (int callno, struct iax_ies *ies) |
| static unsigned char | compress_subclass (int subclass) |
| static void | construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) |
| static int | create_addr (const char *peername, struct sockaddr_in *sin, struct create_addr_info *cai) |
| static int | decode_frame (aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
| static int | decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
| static void | delete_users (void) |
| static void | destroy_firmware (struct iax_firmware *cur) |
| static void | destroy_peer (struct iax2_peer *peer) |
| static void | destroy_user (struct iax2_user *user) |
| static void | dp_lookup (int callno, const char *context, const char *callednum, const char *callerid, int skiplock) |
| static void * | dp_lookup_thread (void *data) |
| static int | encrypt_frame (aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen) |
| static int | expire_registry (void *data) |
| static struct iax2_dpcache * | find_cache (struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority) |
| static int | find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int lockpeer, int sockfd) |
| static struct iax2_thread * | find_idle_thread (void) |
| static struct iax2_peer * | find_peer (const char *name, int realtime) |
| static struct iax2_trunk_peer * | find_tpeer (struct sockaddr_in *sin, int fd) |
| static unsigned int | fix_peerts (struct timeval *tv, int callno, unsigned int ts) |
| static void | free_context (struct iax2_context *con) |
| static int | function_iaxpeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
| static int | get_auth_methods (char *value) |
| static int | get_encrypt_methods (const char *s) |
| static int | get_from_jb (void *p) |
| static int | handle_error (void) |
| static int | iax2_ack_registry (struct iax_ies *ies, struct sockaddr_in *sin, int callno) |
| Acknowledgment received for OUR registration. | |
| static int | iax2_answer (struct ast_channel *c) |
| static enum ast_bridge_result | iax2_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
| static int | iax2_call (struct ast_channel *c, char *dest, int timeout) |
| static int | iax2_canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
| part of the IAX2 dial plan switch interface | |
| static unsigned int | iax2_datetime (const char *tz) |
| static void | iax2_destroy (int callno) |
| static void | iax2_destroy_helper (struct chan_iax2_pvt *pvt) |
| static int | iax2_devicestate (void *data) |
| Part of the device state notification system ---. | |
| static int | iax2_digit_begin (struct ast_channel *c, char digit) |
| static int | iax2_digit_end (struct ast_channel *c, char digit, unsigned int duration) |
| static int | iax2_do_debug (int fd, int argc, char *argv[]) |
| static int | iax2_do_jb_debug (int fd, int argc, char *argv[]) |
| static int | iax2_do_register (struct iax2_registry *reg) |
| static int | iax2_do_register_s (void *data) |
| static int | iax2_do_trunk_debug (int fd, int argc, char *argv[]) |
| static void | iax2_dprequest (struct iax2_dpcache *dp, int callno) |
| static int | iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
| Execute IAX2 dialplan switch. | |
| static int | iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
| Part of the IAX2 switch interface. | |
| static int | iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan) |
| static void | iax2_frame_free (struct iax_frame *fr) |
| static int | iax2_getpeername (struct sockaddr_in sin, char *host, int len, int lockpeer) |
| static int | iax2_getpeertrunk (struct sockaddr_in sin) |
| static int | iax2_hangup (struct ast_channel *c) |
| static int | iax2_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen) |
| static int | iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
| Part of the IAX2 Switch interface. | |
| static int | iax2_no_debug (int fd, int argc, char *argv[]) |
| static int | iax2_no_jb_debug (int fd, int argc, char *argv[]) |
| static int | iax2_no_trunk_debug (int fd, int argc, char *argv[]) |
| static int | iax2_poke_noanswer (void *data) |
| static int | iax2_poke_peer (struct iax2_peer *peer, int heldcall) |
| static int | iax2_poke_peer_s (void *data) |
| static int | iax2_predestroy (int callno) |
| static void * | iax2_process_thread (void *data) |
| static void | iax2_process_thread_cleanup (void *data) |
| static int | iax2_prov_app (struct ast_channel *chan, void *data) |
| static int | iax2_prov_cmd (int fd, int argc, char *argv[]) |
| static char * | iax2_prov_complete_template_3rd (const char *line, const char *word, int pos, int state) |
| static int | iax2_provision (struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force) |
| static int | iax2_prune_realtime (int fd, int argc, char *argv[]) |
| static int | iax2_queue_frame (int callno, struct ast_frame *f) |
| static struct ast_frame * | iax2_read (struct ast_channel *c) |
| static int | iax2_register (char *value, int lineno) |
| static int | iax2_reload (int fd, int argc, char *argv[]) |
| static struct ast_channel * | iax2_request (const char *type, int format, void *data, int *cause) |
| static int | iax2_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final) |
| static int | iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen) |
| static int | iax2_sendimage (struct ast_channel *c, struct ast_frame *img) |
| static int | iax2_sendtext (struct ast_channel *c, const char *text) |
| static int | iax2_setoption (struct ast_channel *c, int option, void *data, int datalen) |
| static int | iax2_show_cache (int fd, int argc, char *argv[]) |
| static int | iax2_show_channels (int fd, int argc, char *argv[]) |
| static int | iax2_show_firmware (int fd, int argc, char *argv[]) |
| static int | iax2_show_netstats (int fd, int argc, char *argv[]) |
| static int | iax2_show_peer (int fd, int argc, char *argv[]) |
| Show one peer in detail. | |
| static int | iax2_show_peers (int fd, int argc, char *argv[]) |
| static int | iax2_show_registry (int fd, int argc, char *argv[]) |
| static int | iax2_show_stats (int fd, int argc, char *argv[]) |
| static int | iax2_show_threads (int fd, int argc, char *argv[]) |
| static int | iax2_show_users (int fd, int argc, char *argv[]) |
| static int | iax2_start_transfer (unsigned short callno0, unsigned short callno1, int mediaonly) |
| static int | iax2_test_losspct (int fd, int argc, char *argv[]) |
| static int | iax2_transfer (struct ast_channel *c, const char *dest) |
| static int | iax2_transmit (struct iax_frame *fr) |
| static int | iax2_trunk_expired (struct iax2_trunk_peer *tpeer, struct timeval *now) |
| static int | iax2_trunk_queue (struct chan_iax2_pvt *pvt, struct iax_frame *fr) |
| static int | iax2_vnak (int callno) |
| static int | iax2_write (struct ast_channel *c, struct ast_frame *f) |
| static int | iax_check_version (char *dev) |
| static void | iax_debug_output (const char *data) |
| static void | iax_error_output (const char *data) |
| static int | iax_firmware_append (struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc) |
| static int | iax_park (struct ast_channel *chan1, struct ast_channel *chan2) |
| static void * | iax_park_thread (void *stuff) |
| static struct iax_frame * | iaxfrdup2 (struct iax_frame *fr) |
| static void | insert_idle_thread (struct iax2_thread *thread) |
| static void | jb_debug_output (const char *fmt,...) |
| static void | jb_error_output (const char *fmt,...) |
| static void | jb_warning_output (const char *fmt,...) |
| static int | load_module (void) |
| Load IAX2 module, load configuraiton ---. | |
| static void | lock_both (unsigned short callno0, unsigned short callno1) |
| static int | make_trunk (unsigned short callno, int locked) |
| static int | manager_iax2_show_netstats (struct mansession *s, const struct message *m) |
| static int | manager_iax2_show_peers (struct mansession *s, const struct message *m) |
| static int | match (struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur) |
| static void | memcpy_decrypt (unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx) |
| static void | memcpy_encrypt (unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx) |
| static void | merge_encryption (struct chan_iax2_pvt *p, unsigned int enc) |
| static void * | network_thread (void *ignore) |
| static struct chan_iax2_pvt * | new_iax (struct sockaddr_in *sin, int lockpeer, 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_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 void | prune_peers (void) |
| static void | prune_users (void) |
| static int | raw_hangup (struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd) |
| static struct iax2_peer * | realtime_peer (const char *peername, struct sockaddr_in *sin) |
| static void | realtime_update_peer (const char *peername, struct sockaddr_in *sin, time_t regtime) |
| static struct iax2_user * | realtime_user (const char *username) |
| static void | reg_source_db (struct iax2_peer *p) |
| static void | register_peer_exten (struct iax2_peer *peer, int onoff) |
| static int | register_verify (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
| Verify inbound registration. | |
| static int | registry_authrequest (const char *name, int callno) |
| static int | registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin) |
| static char * | regstate2str (int regstate) |
| static int | reload (void) |
| static int | reload_config (void) |
| static void | reload_firmware (void) |
| static void | save_rr (struct iax_frame *fr, struct iax_ies *ies) |
| static void * | sched_thread (void *ignore) |
| static int | schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout) |
| static int | send_command (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
| static int | send_command_final (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
| static int | send_command_immediate (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
| static int | send_command_locked (unsigned short callno, char, int, unsigned int, const unsigned char *, int, int) |
| static int | send_command_transfer (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int) |
| static int | send_lagrq (void *data) |
| static int | send_packet (struct iax_frame *f) |
| static int | send_ping (void *data) |
| static int | send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now) |
| static int | set_config (char *config_file, int reload) |
| Load configuration. | |
| static void | set_timing (void) |
| static void | signal_condition (ast_mutex_t *lock, ast_cond_t *cond) |
| static int | socket_process (struct iax2_thread *thread) |
| static int | socket_read (int *id, int fd, short events, void *cbdata) |
| static void | spawn_dp_lookup (int callno, const char *context, const char *callednum, const char *callerid) |
| static int | start_network_thread (void) |
| static void | stop_stuff (int callno) |
| static int | timing_read (int *id, int fd, short events, void *cbdata) |
| static int | transmit_trunk (struct iax_frame *f, struct sockaddr_in *sin, int sockfd) |
| static int | try_firmware (char *s) |
| static int | try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
| static int | uncompress_subclass (unsigned char csub) |
| static int | unload_module (void) |
| static void | unlock_both (unsigned short callno0, unsigned short callno1) |
| static void | unwrap_timestamp (struct iax_frame *fr) |
| static void | update_jbsched (struct chan_iax2_pvt *pvt) |
| static void | update_max_nontrunk (void) |
| static void | update_max_trunk (void) |
| static int | update_packet (struct iax_frame *f) |
| static int | update_registry (const char *name, struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh) |
| static void | vnak_retransmit (int callno, int last) |
Variables | |
| static char | accountcode [AST_MAX_ACCOUNT_CODE] |
| static int | adsi = 0 |
| static int | amaflags = 0 |
| static int | authdebug = 1 |
| static int | autokill = 0 |
| static struct ast_cli_entry | cli_iax2 [] |
| static struct ast_cli_entry | cli_iax2_jb_debug_deprecated |
| static struct ast_cli_entry | cli_iax2_no_debug_deprecated |
| static struct ast_cli_entry | cli_iax2_no_jb_debug_deprecated |
| static struct ast_cli_entry | cli_iax2_no_trunk_debug_deprecated |
| static struct ast_cli_entry | cli_iax2_trunk_debug_deprecated |
| static char | context [80] = "default" |
| static char | debug_jb_usage [] |
| static char | debug_trunk_usage [] |
| static char | debug_usage [] |
| static int | defaultsockfd = -1 |
| static int | delayreject = 0 |
| static struct iax2_dpcache * | dpcache |
| static int | global_rtautoclear = 120 |
| static struct ast_flags | globalflags = { 0 } |
| static int | iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH |
| static int | iax2_encryption = 0 |
| enum { ... } | iax2_flags |
| int(*) | iax2_regfunk (const char *username, int onoff) = NULL |
| static char | iax2_reload_usage [] |
| enum { ... } | iax2_state |
| static struct ast_switch | iax2_switch |
| static struct ast_channel_tech | iax2_tech |
| static char | iax2_test_losspct_usage [] |
| static int | iaxactivethreadcount = 0 |
| static int | iaxcompat = 0 |
| static int | iaxdebug = 0 |
| static int | iaxdefaultdpcache = 10 * 60 |
| static int | iaxdefaulttimeout = 5 |
| static int | iaxdynamicthreadcount = 0 |
| static int | iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT |
| ast_custom_function | iaxpeer_function |
| static struct ast_iax2_queue | iaxq |
| static struct chan_iax2_pvt * | iaxs [IAX_MAX_CALLS] |
| static ast_mutex_t | iaxsl [IAX_MAX_CALLS] |
| static int | iaxthreadcount = DEFAULT_THREAD_COUNT |
| static int | iaxtrunkdebug = 0 |
| static struct ast_custom_function | iaxvar_function |
| static struct io_context * | io |
| static int | lagrq_time = 10 |
| static char | language [MAX_LANGUAGE] = "" |
| static struct timeval | lastused [IAX_MAX_CALLS] |
| static int | max_reg_expire |
| static int | max_retries = 4 |
| static int | maxauthreq = 3 |
| static int | maxjitterbuffer = 1000 |
| static int | maxjitterinterps = 10 |
| static int | maxnontrunkcall = 1 |
| static int | maxtrunkcall = TRUNK_CALL_START |
| static int | min_reg_expire |
| static char | mohinterpret [MAX_MUSICCLASS] |
| static char | mohsuggest [MAX_MUSICCLASS] |
| static struct ast_netsock_list * | netsock |
| static pthread_t | netthreadid = AST_PTHREADT_NULL |
| static char | no_debug_jb_usage [] |
| static char | no_debug_trunk_usage [] |
| static char | no_debug_usage [] |
| static struct ast_netsock_list * | outsock |
| static char * | papp = "IAX2Provision" |
| static char * | pdescrip |
| static int | ping_time = 20 |
| 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 ast_firmware_list | waresl |
Definition in file chan_iax2.c.
| #define CACHE_FLAG_CANEXIST (1 << 2) |
Extension can exist
Definition at line 642 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 638 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 652 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 640 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 644 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 646 of file chan_iax2.c.
Referenced by find_cache(), and iax2_show_cache().
| #define CACHE_FLAG_TRANSMITTED (1 << 5) |
Request transmitted
Definition at line 648 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 650 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 121 of file chan_iax2.c.
Referenced by ast_iax2_new(), iax2_call(), and update_jbsched().
| #define DEBUG_SCHED_MULTITHREAD |
Definition at line 109 of file chan_iax2.c.
| #define DEBUG_SUPPORT |
Definition at line 132 of file chan_iax2.c.
| #define DEFAULT_DROP 3 |
Definition at line 127 of file chan_iax2.c.
| #define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 199 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 198 of file chan_iax2.c.
Referenced by build_peer(), and handle_response_peerpoke().
| #define DEFAULT_MAX_THREAD_COUNT 100 |
Definition at line 124 of file chan_iax2.c.
| #define DEFAULT_MAXMS 2000 |
Definition at line 197 of file chan_iax2.c.
| #define DEFAULT_RETRY_TIME 1000 |
| #define DEFAULT_THREAD_COUNT 10 |
Definition at line 123 of file chan_iax2.c.
| #define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 440 of file chan_iax2.c.
Referenced by iax2_trunk_queue().
| #define FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s\n" |
| #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
| #define FORMAT "%-15.15s %-15d %-15d\n" |
| #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" |
| #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
| #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" |
| #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
| #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" |
| #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" |
| #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
| #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
| #define GAMMA (0.01) |
Definition at line 137 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 180 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 188 of file chan_iax2.c.
Referenced by set_config().
| #define IAX_CAPABILITY_LOWFREE |
Value:
Definition at line 193 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 182 of file chan_iax2.c.
Referenced by set_config().
| #define IAX_IOSTATE_IDLE 0 |
Definition at line 674 of file chan_iax2.c.
| #define IAX_IOSTATE_PROCESSING 2 |
Definition at line 676 of file chan_iax2.c.
| #define IAX_IOSTATE_READY 1 |
| #define IAX_IOSTATE_SCHEDREADY 3 |
| #define IAX_TYPE_DYNAMIC 2 |
Definition at line 680 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 112 of file chan_iax2.c.
| #define MAX_JITTER_BUFFER 50 |
Definition at line 437 of file chan_iax2.c.
| #define MAX_RETRY_TIME 10000 |
| #define MAX_TIMESTAMP_SKEW 160 |
maximum difference between actual and predicted ts for sending
Definition at line 443 of file chan_iax2.c.
| #define MAX_TRUNKDATA 640 * 200 |
40ms, uncompressed linear * 200 channels
Definition at line 441 of file chan_iax2.c.
Referenced by iax2_trunk_queue(), and timing_read().
| #define MEMORY_SIZE 100 |
Definition at line 126 of file chan_iax2.c.
| #define MIN_JITTER_BUFFER 10 |
Definition at line 438 of file chan_iax2.c.
| #define MIN_RETRY_TIME 100 |
| #define MIN_REUSE_TIME 60 |
| #define NEW_ALLOW 1 |
| #define NEW_FORCE 2 |
Definition at line 1108 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 120 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 105 of file chan_iax2.c.
Definition at line 909 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 130 of file chan_iax2.c.
Referenced by find_callno(), make_trunk(), update_max_nontrunk(), and update_max_trunk().
| #define TS_GAP_FOR_JB_RESYNC 5000 |
Definition at line 446 of file chan_iax2.c.
| anonymous enum |
Definition at line 233 of file chan_iax2.c.
00233 { 00234 IAX_STATE_STARTED = (1 << 0), 00235 IAX_STATE_AUTHENTICATED = (1 << 1), 00236 IAX_STATE_TBD = (1 << 2), 00237 IAX_STATE_UNCHANGED = (1 << 3), 00238 } iax2_state;
| anonymous enum |
Definition at line 245 of file chan_iax2.c.
00245 { 00246 IAX_HASCALLERID = (1 << 0), /*!< CallerID has been specified */ 00247 IAX_DELME = (1 << 1), /*!< Needs to be deleted */ 00248 IAX_TEMPONLY = (1 << 2), /*!< Temporary (realtime) */ 00249 IAX_TRUNK = (1 << 3), /*!< Treat as a trunk */ 00250 IAX_NOTRANSFER = (1 << 4), /*!< Don't native bridge */ 00251 IAX_USEJITTERBUF = (1 << 5), /*!< Use jitter buffer */ 00252 IAX_DYNAMIC = (1 << 6), /*!< dynamic peer */ 00253 IAX_SENDANI = (1 << 7), /*!< Send ANI along with CallerID */ 00254 /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */ 00255 IAX_ALREADYGONE = (1 << 9), /*!< Already disconnected */ 00256 IAX_PROVISION = (1 << 10), /*!< This is a provisioning request */ 00257 IAX_QUELCH = (1 << 11), /*!< Whether or not we quelch audio */ 00258 IAX_ENCRYPTED = (1 << 12), /*!< Whether we should assume encrypted tx/rx */ 00259 IAX_KEYPOPULATED = (1 << 13), /*!< Whether we have a key populated */ 00260 IAX_CODEC_USER_FIRST = (1 << 14), /*!< are we willing to let the other guy choose the codec? */ 00261 IAX_CODEC_NOPREFS = (1 << 15), /*!< Force old behaviour by turning off prefs */ 00262 IAX_CODEC_NOCAP = (1 << 16), /*!< only consider requested format and ignore capabilities*/ 00263 IAX_RTCACHEFRIENDS = (1 << 17), /*!< let realtime stay till your reload */ 00264 IAX_RTUPDATE = (1 << 18), /*!< Send a realtime update */ 00265 IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */ 00266 IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 00267 IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */ 00268 IAX_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */ 00269 IAX_TRANSFERMEDIA = (1 << 23), /*!< When doing IAX2 transfers, transfer media only */ 00270 IAX_MAXAUTHREQ = (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */ 00271 } iax2_flags;
| enum iax_reg_state |
| REG_STATE_UNREGISTERED | |
| REG_STATE_REGSENT | |
| REG_STATE_AUTHSENT | |
| REG_STATE_REGISTERED | |
| REG_STATE_REJECTED | |
| REG_STATE_TIMEOUT | |
| REG_STATE_NOAUTH |
Definition at line 392 of file chan_iax2.c.
00392 { 00393 REG_STATE_UNREGISTERED = 0, 00394 REG_STATE_REGSENT, 00395 REG_STATE_AUTHSENT, 00396 REG_STATE_REGISTERED, 00397 REG_STATE_REJECTED, 00398 REG_STATE_TIMEOUT, 00399 REG_STATE_NOAUTH 00400 };
| enum iax_transfer_state |
| TRANSFER_NONE | |
| TRANSFER_BEGIN | |
| TRANSFER_READY | |
| TRANSFER_RELEASED | |
| TRANSFER_PASSTHROUGH | |
| TRANSFER_MBEGIN | |
| TRANSFER_MREADY | |
| TRANSFER_MRELEASED | |
| TRANSFER_MPASSTHROUGH | |
| TRANSFER_MEDIA | |
| TRANSFER_MEDIAPASS |
Definition at line 402 of file chan_iax2.c.
00402 { 00403 TRANSFER_NONE = 0, 00404 TRANSFER_BEGIN, 00405 TRANSFER_READY, 00406 TRANSFER_RELEASED, 00407 TRANSFER_PASSTHROUGH, 00408 TRANSFER_MBEGIN, 00409 TRANSFER_MREADY, 00410 TRANSFER_MRELEASED, 00411 TRANSFER_MPASSTHROUGH, 00412 TRANSFER_MEDIA, 00413 TRANSFER_MEDIAPASS 00414 };
| static void __attempt_transmit | ( | void * | data | ) | [static] |
Definition at line 1835 of file chan_iax2.c.
References chan_iax2_pvt::addr, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), attempt_transmit(), chan_iax2_pvt::error, f, ast_frame::frametype, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxq, iaxs, iaxsl, LOG_WARNING, MAX_RETRY_TIME, chan_iax2_pvt::owner, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), send_packet(), ast_frame::subclass, update_packet(), and iax2_registry::us.
Referenced by attempt_transmit().
01836 { 01837 /* Attempt to transmit the frame to the remote peer... 01838 Called without iaxsl held. */ 01839 struct iax_frame *f = data; 01840 int freeme=0; 01841 int callno = f->callno; 01842 /* Make sure this call is still active */ 01843 if (callno) 01844 ast_mutex_lock(&iaxsl[callno]); 01845 if (callno && iaxs[callno]) { 01846 if ((f->retries < 0) /* Already ACK'd */ || 01847 (f->retries >= max_retries) /* Too many attempts */) { 01848 /* Record an error if we've transmitted too many times */ 01849 if (f->retries >= max_retries) { 01850 if (f->transfer) { 01851 /* Transfer timeout */ 01852 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 01853 } else if (f->final) { 01854 if (f->final) 01855 iax2_destroy(callno); 01856 } else { 01857 if (iaxs[callno]->owner) 01858 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); 01859 iaxs[callno]->error = ETIMEDOUT; 01860 if (iaxs[callno]->owner) { 01861 struct ast_frame fr = { 0, }; 01862 /* Hangup the fd */ 01863 fr.frametype = AST_FRAME_CONTROL; 01864 fr.subclass = AST_CONTROL_HANGUP; 01865 iax2_queue_frame(callno, &fr); 01866 /* Remember, owner could disappear */ 01867 if (iaxs[callno]->owner) 01868 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 01869 } else { 01870 if (iaxs[callno]->reg) { 01871 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 01872 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 01873 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 01874 } 01875 iax2_destroy(callno); 01876 } 01877 } 01878 01879 } 01880 freeme++; 01881 } else { 01882 /* Update it if it needs it */ 01883 update_packet(f); 01884 /* Attempt transmission */ 01885 send_packet(f); 01886 f->retries++; 01887 /* Try again later after 10 times as long */ 01888 f->retrytime *= 10; 01889 if (f->retrytime > MAX_RETRY_TIME) 01890 f->retrytime = MAX_RETRY_TIME; 01891 /* Transfer messages max out at one second */ 01892 if (f->transfer && (f->retrytime > 1000)) 01893 f->retrytime = 1000; 01894 f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f); 01895 } 01896 } else { 01897 /* Make sure it gets freed */ 01898 f->retries = -1; 01899 freeme++; 01900 } 01901 if (callno) 01902 ast_mutex_unlock(&iaxsl[callno]); 01903 /* Do not try again */ 01904 if (freeme) { 01905 /* Don't attempt delivery, just remove it from the queue */ 01906 AST_LIST_LOCK(&iaxq.queue); 01907 AST_LIST_REMOVE(&iaxq.queue, f, list); 01908 iaxq.count--; 01909 AST_LIST_UNLOCK(&iaxq.queue); 01910 f->retrans = -1; 01911 /* Free the IAX frame */ 01912 iax2_frame_free(f); 01913 } 01914 }
| static void __auth_reject | ( | void * | nothing | ) | [static] |
Definition at line 5792 of file chan_iax2.c.
References AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_FACILITY_REJECTED, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), IAX_COMMAND_REGREJ, IAX_COMMAND_REJECT, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, and send_command_final().
Referenced by auth_reject().
05793 { 05794 /* Called from IAX thread only, without iaxs lock */ 05795 int callno = (int)(long)(nothing); 05796 struct iax_ie_data ied; 05797 ast_mutex_lock(&iaxsl[callno]); 05798 if (iaxs[callno]) { 05799 memset(&ied, 0, sizeof(ied)); 05800 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 05801 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 05802 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 05803 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 05804 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 05805 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 05806 } 05807 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 05808 } 05809 ast_mutex_unlock(&iaxsl[callno]); 05810 }
| static void __auto_congest | ( | void * | nothing | ) | [static] |
Definition at line 2711 of file chan_iax2.c.
References AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), f, iax2_queue_frame(), iaxs, iaxsl, chan_iax2_pvt::initid, LOG_NOTICE, and PTR_TO_CALLNO.
Referenced by auto_congest().
02712 { 02713 int callno = PTR_TO_CALLNO(nothing); 02714 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 02715 ast_mutex_lock(&iaxsl[callno]); 02716 if (iaxs[callno]) { 02717 iaxs[callno]->initid = -1; 02718 iax2_queue_frame(callno, &f); 02719 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 02720 } 02721 ast_mutex_unlock(&iaxsl[callno]); 02722 }
| static void __auto_hangup | ( | void * | nothing | ) | [static] |
Definition at line 5844 of file chan_iax2.c.
References AST_CAUSE_NO_USER_RESPONSE, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), IAX_COMMAND_HANGUP, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, and send_command_final().
Referenced by auto_hangup().
05845 { 05846 /* Called from IAX thread only, without iaxs lock */ 05847 int callno = (int)(long)(nothing); 05848 struct iax_ie_data ied; 05849 ast_mutex_lock(&iaxsl[callno]); 05850 if (iaxs[callno]) { 05851 memset(&ied, 0, sizeof(ied)); 05852 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 05853 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 05854 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 05855 } 05856 ast_mutex_unlock(&iaxsl[callno]); 05857 }
| static int __do_deliver | ( | void * | data | ) | [static] |
Definition at line 1591 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().
01592 { 01593 /* Just deliver the packet by using queueing. This is called by 01594 the IAX thread with the iaxsl lock held. */ 01595 struct iax_frame *fr = data; 01596 fr->retrans = -1; 01597 fr->af.has_timing_info = 0; 01598 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 01599 iax2_queue_frame(fr->callno, &fr->af); 01600 /* Free our iax frame */ 01601 iax2_frame_free(fr); 01602 /* And don't run again */ 01603 return 0; 01604 }
| static void __expire_registry | ( | void * | data | ) | [static] |
Definition at line 5517 of file chan_iax2.c.
References iax2_peer::addr, ast_db_del(), ast_device_state_changed(), AST_LIST_LOCK, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_set_flag, ast_test_flag, EVENT_FLAG_SYSTEM, iax2_peer::expire, iax2_peer::expiry, globalflags, iax2_regfunk, IAX_DELME, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_TEMPONLY, manager_event(), name, prune_peers(), realtime_update_peer(), and register_peer_exten().
Referenced by expire_registry().
05518 { 05519 char *name = data; 05520 struct iax2_peer *p = NULL; 05521 05522 /* Go through and grab this peer... and if it needs to be removed... then do it */ 05523 AST_LIST_LOCK(&peers); 05524 AST_LIST_TRAVERSE_SAFE_BEGIN(&peers, p, entry) { 05525 if (!strcasecmp(p->name, name)) { 05526 p->expire = -1; 05527 break; 05528 } 05529 } 05530 AST_LIST_TRAVERSE_SAFE_END 05531 AST_LIST_UNLOCK(&peers); 05532 05533 /* Peer is already gone for whatever reason */ 05534 if (!p) 05535 return; 05536 05537 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", p->name); 05538 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 05539 realtime_update_peer(p->name, &p->addr, 0); 05540 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", p->name); 05541 /* Reset the address */ 05542 memset(&p->addr, 0, sizeof(p->addr)); 05543 /* Reset expiry value */ 05544 p->expiry = min_reg_expire; 05545 if (!ast_test_flag(p, IAX_TEMPONLY)) 05546 ast_db_del("IAX/Registry", p->name); 05547 register_peer_exten(p, 0); 05548 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05549 if (iax2_regfunk) 05550 iax2_regfunk(p->name, 0); 05551 05552 if (ast_test_flag(p, IAX_RTAUTOCLEAR)) { 05553 ast_set_flag(p, IAX_DELME); 05554 prune_peers(); 05555 } 05556 }
| static void __get_from_jb | ( | void * | p | ) | [static] |
Definition at line 2232 of file chan_iax2.c.
References __do_deliver(), ast_backtrace(), ast_codec_interp_len(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_tvadd(), jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, iaxsl, chan_iax2_pvt::jb, JB_DROP, JB_EMPTY, jb_get(), JB_INTERP, jb_next(), JB_NOFRAME, JB_OK, chan_iax2_pvt::jbid, LOG_ERROR, jb_frame::ms, ast_frame::offset, PTR_TO_CALLNO, chan_iax2_pvt::rxcore, ast_frame::samples, ast_frame::src, ast_frame::subclass, update_jbsched(), and chan_iax2_pvt::voiceformat.
Referenced by get_from_jb().
02233 { 02234 int callno = PTR_TO_CALLNO(p); 02235 struct chan_iax2_pvt *pvt = NULL; 02236 struct iax_frame *fr; 02237 jb_frame frame; 02238 int ret; 02239 long now; 02240 long next; 02241 struct timeval tv; 02242 02243 /* Make sure we have a valid private structure before going on */ 02244 ast_mutex_lock(&iaxsl[callno]); 02245 pvt = iaxs[callno]; 02246 if (!pvt) { 02247 /* No go! */ 02248 ast_mutex_unlock(&iaxsl[callno]); 02249 return; 02250 } 02251 02252 if( pvt->jb == NULL ) { 02253 ast_log( LOG_ERROR, "__get_from_jb(): why p->jb is null?\n" ); 02254 ast_backtrace(); 02255 return; 02256 } 02257 02258 pvt->jbid = -1; 02259 02260 gettimeofday(&tv,NULL); 02261 /* round up a millisecond since ast_sched_runq does; */ 02262 /* prevents us from spinning while waiting for our now */ 02263 /* to catch up with runq's now */ 02264 tv.tv_usec += 1000; 02265 02266 now = ast_tvdiff_ms(tv, pvt->rxcore); 02267 02268 if(now >= (next = jb_next(pvt->jb))) { 02269 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat)); 02270 switch(ret) { 02271 case JB_OK: 02272 fr = frame.data; 02273 __do_deliver(fr); 02274 break; 02275 case JB_INTERP: 02276 { 02277 struct ast_frame af = { 0, }; 02278 02279 /* create an interpolation frame */ 02280 af.frametype = AST_FRAME_VOICE; 02281 af.subclass = pvt->voiceformat; 02282 af.samples = frame.ms * 8; 02283 af.src = "IAX2 JB interpolation"; 02284 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 02285 af.offset = AST_FRIENDLY_OFFSET; 02286 02287 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 02288 * which we'd need to malloc, and then it would free it. That seems like a drag */ 02289 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 02290 iax2_queue_frame(callno, &af); 02291 } 02292 break; 02293 case JB_DROP: 02294 iax2_frame_free(frame.data); 02295 break; 02296 case JB_NOFRAME: 02297 case JB_EMPTY: 02298 /* do nothing */ 02299 break; 02300 default: 02301 /* shouldn't happen */ 02302 break; 02303 } 02304 } 02305 update_jbsched(pvt); 02306 ast_mutex_unlock(&iaxsl[callno]); 02307 }
| static void __iax2_do_register_s | ( | void * | data | ) | [static] |
Definition at line 5234 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
05235 { 05236 struct iax2_registry *reg = data; 05237 reg->expire = -1; 05238 iax2_do_register(reg); 05239 }
| static void __iax2_poke_noanswer | ( | void * | data | ) | [static] |
Definition at line 7953 of file chan_iax2.c.
References ast_device_state_changed(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), iax2_peer::callno, EVENT_FLAG_SYSTEM, iax2_destroy(), iax2_poke_peer_s(), iaxsl, iax2_peer::lastms, LOG_NOTICE, manager_event(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, and sched.
Referenced by iax2_poke_noanswer().
07954 { 07955 struct iax2_peer *peer = data; 07956 if (peer->lastms > -1) { 07957 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 07958 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 07959 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07960 } 07961 if (peer->callno > 0) { 07962 ast_mutex_lock(&iaxsl[peer->callno]); 07963 iax2_destroy(peer->callno); 07964 ast_mutex_unlock(&iaxsl[peer->callno]); 07965 } 07966 peer->callno = 0; 07967 peer->lastms = -1; 07968 /* Try again quickly */ 07969 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer); 07970 }
| static void __iax2_poke_peer_s | ( | void * | data | ) | [static] |
Definition at line 5907 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by iax2_poke_peer_s().
05908 { 05909 struct iax2_peer *peer = data; 05910 iax2_poke_peer(peer, 0); 05911 }
| static int __iax2_show_peers | ( | int | manager, | |
| int | fd, | |||
| struct mansession * | s, | |||
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 4059 of file chan_iax2.c.
References iax2_peer::addr, ast_cli(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_test_flag, astman_append(), iax2_peer::encmethods, FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, name, peer_status(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and s.
Referenced by iax2_show_peers(), and manager_iax2_show_peers().
04060 { 04061 regex_t regexbuf; 04062 int havepattern = 0; 04063 int total_peers = 0; 04064 int online_peers = 0; 04065 int offline_peers = 0; 04066 int unmonitored_peers = 0; 04067 04068 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 04069 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 04070 04071 struct iax2_peer *peer = NULL; 04072 char name[256]; 04073 int registeredonly=0; 04074 char *term = manager ? "\r\n" : "\n"; 04075 04076 switch (argc) { 04077 case 6: 04078 if (!strcasecmp(argv[3], "registered")) 04079 registeredonly = 1; 04080 else 04081 return RESULT_SHOWUSAGE; 04082 if (!strcasecmp(argv[4], "like")) { 04083 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 04084 return RESULT_SHOWUSAGE; 04085 havepattern = 1; 04086 } else 04087 return RESULT_SHOWUSAGE; 04088 break; 04089 case 5: 04090 if (!strcasecmp(argv[3], "like")) { 04091 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04092 return RESULT_SHOWUSAGE; 04093 havepattern = 1; 04094 } else 04095 return RESULT_SHOWUSAGE; 04096 break; 04097 case 4: 04098 if (!strcasecmp(argv[3], "registered")) 04099 registeredonly = 1; 04100 else 04101 return RESULT_SHOWUSAGE; 04102 break; 04103 case 3: 04104 break; 04105 default: 04106 return RESULT_SHOWUSAGE; 04107 } 04108 04109 04110 if (s) 04111 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04112 else 04113 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04114 04115 AST_LIST_LOCK(&peers); 04116 AST_LIST_TRAVERSE(&peers, peer, entry) { 04117 char nm[20]; 04118 char status[20]; 04119 char srch[2000]; 04120 int retstatus; 04121 04122 if (registeredonly && !peer->addr.sin_addr.s_addr) 04123 continue; 04124 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 04125 continue; 04126 04127 if (!ast_strlen_zero(peer->username)) 04128 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 04129 else 04130 ast_copy_string(name, peer->name, sizeof(name)); 04131 04132 retstatus = peer_status(peer, status, sizeof(status)); 04133 if (retstatus > 0) 04134 online_peers++; 04135 else if (!retstatus) 04136 offline_peers++; 04137 else 04138 unmonitored_peers++; 04139 04140 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 04141 04142 snprintf(srch, sizeof(srch), FORMAT, name, 04143 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04144 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04145 nm, 04146 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04147 peer->encmethods ? "(E)" : " ", status, term); 04148 04149 if (s) 04150 astman_append(s, FORMAT, name, 04151 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)", 04152 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04153 nm, 04154 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04155 peer->encmethods ? "(E)" : " ", status, term); 04156 else 04157 ast_cli(fd, FORMAT, name, 04158 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04159 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04160 nm, 04161 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04162 peer->encmethods ? "(E)" : " ", status, term); 04163 total_peers++; 04164 } 04165 AST_LIST_UNLOCK(&peers); 04166 04167 if (s) 04168 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04169 else 04170 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04171 04172 if (havepattern) 04173 regfree(®exbuf); 04174 04175 return RESULT_SUCCESS; 04176 #undef FORMAT 04177 #undef FORMAT2 04178 }
| static int __schedule_action | ( | void(*)(void *data) | func, | |
| void * | data, | |||
| const char * | funcname | |||
| ) | [static] |
Definition at line 884 of file chan_iax2.c.
References ast_log(), find_idle_thread(), IAX_IOSTATE_SCHEDREADY, LOG_NOTICE, signal_condition(), t, and thread.
00885 { 00886 struct iax2_thread *thread = NULL; 00887 static time_t lasterror; 00888 static time_t t; 00889 00890 thread = find_idle_thread(); 00891 00892 if (thread != NULL) { 00893 thread->schedfunc = func; 00894 thread->scheddata = data; 00895 thread->iostate = IAX_IOSTATE_SCHEDREADY; 00896 #ifdef DEBUG_SCHED_MULTITHREAD 00897 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 00898 #endif 00899 signal_condition(&thread->lock, &thread->cond); 00900 return 0; 00901 } 00902 time(&t); 00903 if (t != lasterror) 00904 ast_log(LOG_NOTICE, "Out of idle IAX2 threads for scheduling!\n"); 00905 lasterror = t; 00906 00907 return -1; 00908 }
| 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 4558 of file chan_iax2.c.
References f, and iax2_send().
Referenced by send_command(), send_command_final(), send_command_immediate(), and send_command_transfer().
04560 { 04561 struct ast_frame f = { 0, }; 04562 04563 f.frametype = type; 04564 f.subclass = command; 04565 f.datalen = datalen; 04566 f.src = __FUNCTION__; 04567 f.data = (void *) data; 04568 04569 return iax2_send(i, &f, ts, seqno, now, transfer, final); 04570 }
| static void __send_lagrq | ( | void * | data | ) | [static] |
Definition at line 948 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), IAX_COMMAND_LAGRQ, iaxs, iaxsl, chan_iax2_pvt::lagid, sched, send_command(), and send_lagrq().
Referenced by send_lagrq().
00949 { 00950 int callno = (long)data; 00951 /* Ping only if it's real not if it's bridged */ 00952 ast_mutex_lock(&iaxsl[callno]); 00953 if (iaxs[callno] && iaxs[callno]->lagid != -1) { 00954 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 00955 iaxs[callno]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 00956 } 00957 ast_mutex_unlock(&iaxsl[callno]); 00958 }
| static void __send_ping | ( | void * | data | ) | [static] |
Definition at line 914 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), IAX_COMMAND_PING, iaxs, iaxsl, chan_iax2_pvt::pingid, sched, send_command(), and send_ping().
Referenced by send_ping().
00915 { 00916 int callno = (long)data; 00917 ast_mutex_lock(&iaxsl[callno]); 00918 if (iaxs[callno] && iaxs[callno]->pingid != -1) { 00919 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 00920 iaxs[callno]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, data); 00921 } 00922 ast_mutex_unlock(&iaxsl[callno]); 00923 }
| static int __unload_module | ( | void | ) | [static] |
Definition at line 10049 of file chan_iax2.c.
References 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_provision_unload(), iaxactivethreadcount, iaxq, iaxs, iaxsl, ast_firmware_list::lock, netsock, outsock, sched, sched_context_destroy(), thread, and waresl.
Referenced by load_module(), and unload_module().
10050 { 10051 struct iax2_thread *thread = NULL; 10052 int x; 10053 10054 /* Make sure threads do not hold shared resources when they are canceled */ 10055 10056 /* Grab the sched lock resource to keep it away from threads about to die */ 10057 /* Cancel the network thread, close the net socket */ 10058 if (netthreadid != AST_PTHREADT_NULL) { 10059 AST_LIST_LOCK(&iaxq.queue); 10060 ast_mutex_lock(&sched_lock); 10061 pthread_cancel(netthreadid); 10062 ast_cond_signal(&sched_cond); 10063 ast_mutex_unlock(&sched_lock); /* Release the schedule lock resource */ 10064 AST_LIST_UNLOCK(&iaxq.queue); 10065 pthread_join(netthreadid, NULL); 10066 } 10067 if (schedthreadid != AST_PTHREADT_NULL) { 10068 ast_mutex_lock(&sched_lock); 10069 pthread_cancel(schedthreadid); 10070 ast_cond_signal(&sched_cond); 10071 ast_mutex_unlock(&sched_lock); 10072 pthread_join(schedthreadid, NULL); 10073 } 10074 10075 /* Call for all threads to halt */ 10076 AST_LIST_LOCK(&idle_list); 10077 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) { 10078 AST_LIST_REMOVE_CURRENT(&idle_list, list); 10079 pthread_cancel(thread->threadid); 10080 } 10081 AST_LIST_TRAVERSE_SAFE_END 10082 AST_LIST_UNLOCK(&idle_list); 10083 10084 AST_LIST_LOCK(&active_list); 10085 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) { 10086 AST_LIST_REMOVE_CURRENT(&active_list, list); 10087 pthread_cancel(thread->threadid); 10088 } 10089 AST_LIST_TRAVERSE_SAFE_END 10090 AST_LIST_UNLOCK(&active_list); 10091 10092 AST_LIST_LOCK(&dynamic_list); 10093 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) { 10094 AST_LIST_REMOVE_CURRENT(&dynamic_list, list); 10095 pthread_cancel(thread->threadid); 10096 } 10097 AST_LIST_TRAVERSE_SAFE_END 10098 AST_LIST_UNLOCK(&dynamic_list); 10099 10100 AST_LIST_HEAD_DESTROY(&iaxq.queue); 10101 10102 /* Wait for threads to exit */ 10103 while(0 < iaxactivethreadcount) 10104 usleep(10000); 10105 10106 ast_netsock_release(netsock); 10107 ast_netsock_release(outsock); 10108 for (x=0;x<IAX_MAX_CALLS;x++) 10109 if (iaxs[x]) 10110 iax2_destroy(x); 10111 ast_manager_unregister( "IAXpeers" ); 10112 ast_manager_unregister( "IAXnetstats" ); 10113 ast_unregister_application(papp); 10114 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 10115 ast_unregister_switch(&iax2_switch); 10116 ast_channel_unregister(&iax2_tech); 10117 delete_users(); 10118 iax_provision_unload(); 10119 sched_context_destroy(sched); 10120 10121 ast_mutex_destroy(&waresl.lock); 10122 10123 for (x = 0; x < IAX_MAX_CALLS; x++) 10124 ast_mutex_destroy(&iaxsl[x]); 10125 10126 return 0; 10127 }
| static int acf_iaxvar_read | ( | struct ast_channel * | chan, | |
| char * | cmd, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 6289 of file chan_iax2.c.
References pbx_builtin_getvar_helper().
06290 { 06291 const char *value; 06292 char tmp[256]; 06293 snprintf(tmp, sizeof(tmp), "~IAX2~%s", data); 06294 value = pbx_builtin_getvar_helper(chan, tmp); 06295 ast_copy_string(buf, value ? value : "", len); 06296 return 0; 06297 }
| static int acf_iaxvar_write | ( | struct ast_channel * | chan, | |
| char * | cmd, | |||
| char * | varname, | |||
| const char * | value | |||
| ) | [static] |
Definition at line 6299 of file chan_iax2.c.
References pbx_builtin_setvar_helper().
06300 { 06301 char tmp[256]; 06302 /* Inherit forever */ 06303 snprintf(tmp, sizeof(tmp), "__~IAX2~%s", varname); 06304 pbx_builtin_setvar_helper(chan, tmp, value); 06305 return 0; 06306 }
| static int apply_context | ( | struct iax2_context * | con, | |
| const char * | context | |||
| ) | [static] |
Definition at line 4603 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
04604 { 04605 while(con) { 04606 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 04607 return -1; 04608 con = con->next; 04609 } 04610 return 0; 04611 }
| static int ast_cli_netstats | ( | struct mansession * | s, | |
| int | fd, | |||
| int | limit_fmt | |||
| ) | [static] |
Definition at line 4386 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_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), iax_rr::jitter, jb_info::jitter, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, jb_info::min, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::pingtime, chan_iax2_pvt::remote_rr, and s.
Referenced by iax2_show_netstats(), and manager_iax2_show_netstats().
04387 { 04388 int x; 04389 int numchans = 0; 04390 for (x=0;x<IAX_MAX_CALLS;x++) { 04391 ast_mutex_lock(&iaxsl[x]); 04392 if (iaxs[x]) { 04393 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 04394 char *fmt; 04395 jb_info jbinfo; 04396 04397 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04398 jb_getinfo(iaxs[x]->jb, &jbinfo); 04399 localjitter = jbinfo.jitter; 04400 localdelay = jbinfo.current - jbinfo.min; 04401 locallost = jbinfo.frames_lost; 04402 locallosspct = jbinfo.losspct/1000; 04403 localdropped = jbinfo.frames_dropped; 04404 localooo = jbinfo.frames_ooo; 04405 } else { 04406 localjitter = -1; 04407 localdelay = 0; 04408 locallost = -1; 04409 locallosspct = -1; 04410 localdropped = 0; 04411 localooo = -1; 04412 } 04413 if (limit_fmt) 04414 fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n"; 04415 else 04416 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"; 04417 if (s) 04418 04419 astman_append(s, fmt, 04420 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04421 iaxs[x]->pingtime, 04422 localjitter, 04423 localdelay, 04424 locallost, 04425 locallosspct, 04426 localdropped, 04427 localooo, 04428 iaxs[x]->frames_received/1000, 04429 iaxs[x]->remote_rr.jitter, 04430 iaxs[x]->remote_rr.delay, 04431 iaxs[x]->remote_rr.losscnt, 04432 iaxs[x]->remote_rr.losspct, 04433 iaxs[x]->remote_rr.dropped, 04434 iaxs[x]->remote_rr.ooo, 04435 iaxs[x]->remote_rr.packets/1000); 04436 else 04437 ast_cli(fd, fmt, 04438 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04439 iaxs[x]->pingtime, 04440 localjitter, 04441 localdelay, 04442 locallost, 04443 locallosspct, 04444 localdropped, 04445 localooo, 04446 iaxs[x]->frames_received/1000, 04447 iaxs[x]->remote_rr.jitter, 04448 iaxs[x]->remote_rr.delay, 04449 iaxs[x]->remote_rr.losscnt, 04450 iaxs[x]->remote_rr.losspct, 04451 iaxs[x]->remote_rr.dropped, 04452 iaxs[x]->remote_rr.ooo, 04453 iaxs[x]->remote_rr.packets/1000 04454 ); 04455 numchans++; 04456 } 04457 ast_mutex_unlock(&iaxsl[x]); 04458 } 04459 return numchans; 04460 }
| static struct ast_channel* ast_iax2_new | ( | int | callno, | |
| int | state, | |||
| int | capability | |||
| ) | [static] |
Create new call, interface with the PBX core.
Definition at line 3298 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_name, ast_callerid::cid_num, 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().
03299 { 03300 struct ast_channel *tmp; 03301 struct chan_iax2_pvt *i; 03302 struct ast_variable *v = NULL; 03303 03304 if (!(i = iaxs[callno])) { 03305 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 03306 return NULL; 03307 } 03308 03309 /* Don't hold call lock */ 03310 ast_mutex_unlock(&iaxsl[callno]); 03311 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); 03312 ast_mutex_lock(&iaxsl[callno]); 03313 if (!tmp) 03314 return NULL; 03315 tmp->tech = &iax2_tech; 03316 /* We can support any format by default, until we get restricted */ 03317 tmp->nativeformats = capability; 03318 tmp->readformat = ast_best_codec(capability); 03319 tmp->writeformat = ast_best_codec(capability); 03320 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 03321 03322 /* Don't use ast_set_callerid() here because it will 03323 * generate a NewCallerID event before the NewChannel event */ 03324 tmp->cid.cid_num = ast_strdup(i->cid_num); 03325 tmp->cid.cid_name = ast_strdup(i->cid_name); 03326 if (!ast_strlen_zero(i->ani)) 03327 tmp->cid.cid_ani = ast_strdup(i->ani); 03328 else 03329 tmp->cid.cid_ani = ast_strdup(i->cid_num); 03330 tmp->cid.cid_dnid = ast_strdup(i->dnid); 03331 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 03332 tmp->cid.cid_pres = i->calling_pres; 03333 tmp->cid.cid_ton = i->calling_ton; 03334 tmp->cid.cid_tns = i->calling_tns; 03335 if (!ast_strlen_zero(i->language)) 03336 ast_string_field_set(tmp, language, i->language); 03337 if (!ast_strlen_zero(i->accountcode)) 03338 ast_string_field_set(tmp, accountcode, i->accountcode); 03339 if (i->amaflags) 03340 tmp->amaflags = i->amaflags; 03341 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 03342 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 03343 if (i->adsi) 03344 tmp->adsicpe = i->peeradsicpe; 03345 else 03346 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 03347 i->owner = tmp; 03348 i->capability = capability; 03349 if (state != AST_STATE_DOWN) { 03350 if (ast_pbx_start(tmp)) { 03351 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 03352 ast_hangup(tmp); 03353 i->owner = NULL; 03354 return NULL; 03355 } 03356 } 03357 03358 for (v = i->vars ; v ; v = v->next) 03359 pbx_builtin_setvar_helper(tmp, v->name, v->value); 03360 03361 ast_module_ref(ast_module_info->self); 03362 03363 return tmp; 03364 }
| 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 | ( | peers | , | |
| iax2_peer | ||||
| ) | [static] |
| static AST_LIST_HEAD_STATIC | ( | users | , | |
| iax2_user | ||||
| ) | [static] |
| static AST_LIST_HEAD_STATIC | ( | registrations | , | |
| iax2_registry | ||||
| ) | [static] |
| AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
| AST_MODFLAG_DEFAULT | , | |||
| "Inter Asterisk eXchange (Ver 2)" | , | |||
| . | load = load_module, |
|||
| . | unload = unload_module, |
|||
| . | reload = reload | |||
| ) |
| AST_MUTEX_DEFINE_STATIC | ( | dpcache_lock | ) |
| AST_MUTEX_DEFINE_STATIC | ( | tpeerlock | ) |
| AST_MUTEX_DEFINE_STATIC | ( | sched_lock | ) |
| static int attempt_transmit | ( | void * | data | ) | [static] |
Definition at line 1916 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and network_thread().
01917 { 01918 #ifdef SCHED_MULTITHREADED 01919 if (schedule_action(__attempt_transmit, data)) 01920 #endif 01921 __attempt_transmit(data); 01922 return 0; 01923 }
| static int auth_fail | ( | int | callno, | |
| int | failcode | |||
| ) | [static] |
Definition at line 5826 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), auth_reject(), chan_iax2_pvt::authfail, chan_iax2_pvt::authid, iaxs, iaxsl, and sched.
Referenced by socket_process().
05827 { 05828 /* Schedule sending the authentication failure in one second, to prevent 05829 guessing */ 05830 ast_mutex_lock(&iaxsl[callno]); 05831 if (iaxs[callno]) { 05832 iaxs[callno]->authfail = failcode; 05833 if (delayreject) { 05834 if (iaxs[callno]->authid > -1) 05835 ast_sched_del(sched, iaxs[callno]->authid); 05836 iaxs[callno]->authid = ast_sched_add(sched, 1000, auth_reject, (void *)(long)callno); 05837 } else 05838 auth_reject((void *)(long)callno); 05839 } 05840 ast_mutex_unlock(&iaxsl[callno]); 05841 return 0; 05842 }
| static int auth_reject | ( | void * | data | ) | [static] |
Definition at line 5812 of file chan_iax2.c.
References __auth_reject(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::authid, iaxs, iaxsl, and schedule_action.
Referenced by auth_fail().
05813 { 05814 int callno = (int)(long)(data); 05815 ast_mutex_lock(&iaxsl[callno]); 05816 if (iaxs[callno]) 05817 iaxs[callno]->authid = -1; 05818 ast_mutex_unlock(&iaxsl[callno]); 05819 #ifdef SCHED_MULTITHREADED 05820 if (schedule_action(__auth_reject, data)) 05821 #endif 05822 __auth_reject(data); 05823 return 0; 05824 }
| 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 5121 of file chan_iax2.c.
References ast_inet_ntoa(), ast_key_get, AST_KEY_PRIVATE, ast_log(), ast_sign, ast_strlen_zero(), build_enc_keys(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, iax_ie_append_str(), IAX_IE_MD5_RESULT, IAX_IE_PASSWORD, IAX_IE_RSA_RESULT, key(), LOG_NOTICE, md5(), MD5Final(), MD5Init(), and MD5Update().
05122 { 05123 int res = -1; 05124 int x; 05125 if (!ast_strlen_zero(keyn)) { 05126 if (!(authmethods & IAX_AUTH_RSA)) { 05127 if (ast_strlen_zero(secret)) 05128 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)); 05129 } else if (ast_strlen_zero(challenge)) { 05130 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 05131 } else { 05132 char sig[256]; 05133 struct ast_key *key; 05134 key = ast_key_get(keyn, AST_KEY_PRIVATE); 05135 if (!key) { 05136 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 05137 } else { 05138 if (ast_sign(key, (char*)challenge, sig)) { 05139 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 05140 res = -1; 05141 } else { 05142 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 05143 res = 0; 05144 } 05145 } 05146 } 05147 } 05148 /* Fall back */ 05149 if (res && !ast_strlen_zero(secret)) { 05150 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 05151 struct MD5Context md5; 05152 unsigned char digest[16]; 05153 char digres[128]; 05154 MD5Init(&md5); 05155 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 05156 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 05157 MD5Final(digest, &md5); 05158 /* If they support md5, authenticate with it. */ 05159 for (x=0;x<16;x++) 05160 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 05161 if (ecx && dcx) 05162 build_enc_keys(digest, ecx, dcx); 05163 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 05164 res = 0; 05165 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 05166 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 05167 res = 0; 05168 } else 05169 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 05170 } 05171 return res; 05172 }
| 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 5174 of file chan_iax2.c.
References iax2_peer::addr, AST_FRAME_IAX, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, authenticate(), destroy_peer(), IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_KEYPOPULATED, IAX_TEMPONLY, ies, iax2_peer::mask, merge_encryption(), realtime_peer(), and send_command().
Referenced by socket_process().
05175 { 05176 struct iax2_peer *peer = NULL; 05177 /* Start pessimistic */ 05178 int res = -1; 05179 int authmethods = 0; 05180 struct iax_ie_data ied; 05181 05182 memset(&ied, 0, sizeof(ied)); 05183 05184 if (ies->username) 05185 ast_string_field_set(p, username, ies->username); 05186 if (ies->challenge) 05187 ast_string_field_set(p, challenge, ies->challenge); 05188 if (ies->authmethods) 05189 authmethods = ies->authmethods; 05190 if (authmethods & IAX_AUTH_MD5) 05191 merge_encryption(p, ies->encmethods); 05192 else 05193 p->encmethods = 0; 05194 05195 /* Check for override RSA authentication first */ 05196 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 05197 /* Normal password authentication */ 05198 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05199 } else { 05200 AST_LIST_LOCK(&peers); 05201 AST_LIST_TRAVERSE(&peers, peer, entry) { 05202 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 05203 /* No peer specified at our end, or this is the peer */ 05204 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 05205 /* No username specified in peer rule, or this is the right username */ 05206 && (!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))) 05207 /* No specified host, or this is our host */ 05208 ) { 05209 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05210 if (!res) 05211 break; 05212 } 05213 } 05214 AST_LIST_UNLOCK(&peers); 05215 if (!peer) { 05216 /* We checked our list and didn't find one. It's unlikely, but possible, 05217 that we're trying to authenticate *to* a realtime peer */ 05218 if ((peer = realtime_peer(p->peer, NULL))) { 05219 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx); 05220 if (ast_test_flag(peer, IAX_TEMPONLY)) 05221 destroy_peer(peer); 05222 } 05223 } 05224 } 05225 if (ies->encmethods) 05226 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 05227 if (!res) 05228 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 05229 return res; 05230 }
| static int authenticate_request | ( | struct chan_iax2_pvt * | p | ) | [static] |
Definition at line 4846 of file chan_iax2.c.
References AST_CAUSE_CALL_REJECTED, AST_FRAME_IAX, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_random(), ast_set_flag, ast_string_field_set, ast_test_flag, chan_iax2_pvt::authmethods, iax2_user::curauthreq, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_COMMAND_AUTHREQ, IAX_COMMAND_REJECT, IAX_ENCRYPTED, iax_ie_append_byte(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_CHALLENGE, IAX_IE_ENCRYPTION, IAX_IE_USERNAME, IAX_MAXAUTHREQ, iax2_user::maxauthreq, send_command(), and send_command_final().
Referenced by socket_process().
04847 { 04848 struct iax2_user *user = NULL; 04849 struct iax_ie_data ied; 04850 int res = -1, authreq_restrict = 0; 04851 char challenge[10]; 04852 04853 memset(&ied, 0, sizeof(ied)); 04854 04855 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 04856 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 04857 AST_LIST_LOCK(&users); 04858 AST_LIST_TRAVERSE(&users, user, entry) { 04859 if (!strcmp(user->name, p->username)) { 04860 if (user->curauthreq == user->maxauthreq) 04861 authreq_restrict = 1; 04862 else 04863 user->curauthreq++; 04864 break; 04865 } 04866 } 04867 AST_LIST_UNLOCK(&users); 04868 } 04869 04870 /* If the AUTHREQ limit test failed, send back an error */ 04871 if (authreq_restrict) { 04872 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 04873 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 04874 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 04875 return 0; 04876 } 04877 04878 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 04879 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 04880 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 04881 ast_string_field_set(p, challenge, challenge); 04882 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 04883 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 04884 } 04885 if (p->encmethods) 04886 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 04887 04888 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 04889 04890 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 04891 04892 if (p->encmethods) 04893 ast_set_flag(p, IAX_ENCRYPTED); 04894 04895 return res; 04896 }
| static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 4898 of file chan_iax2.c.
References ast_check_signature, ast_clear_flag, ast_key_get, AST_KEY_PUBLIC, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, chan_iax2_pvt::authmethods, iax2_user::curauthreq, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, ies, key(), LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), chan_iax2_pvt::state, and strsep().
Referenced by socket_process().
04899 { 04900 char requeststr[256]; 04901 char md5secret[256] = ""; 04902 char secret[256] = ""; 04903 char rsasecret[256] = ""; 04904 int res = -1; 04905 int x; 04906 struct iax2_user *user = NULL; 04907 04908 AST_LIST_LOCK(&users); 04909 AST_LIST_TRAVERSE(&users, user, entry) { 04910 if (!strcmp(user->name, p->username)) 04911 break; 04912 } 04913 if (user) { 04914 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 04915 user->curauthreq--; 04916 ast_clear_flag(p, IAX_MAXAUTHREQ); 04917 } 04918 ast_string_field_set(p, host, user->name); 04919 } 04920 AST_LIST_UNLOCK(&users); 04921 04922 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 04923 return res; 04924 if (ies->password) 04925 ast_copy_string(secret, ies->password, sizeof(secret)); 04926 if (ies->md5_result) 04927 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 04928 if (ies->rsa_result) 04929 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 04930 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 04931 struct ast_key *key; 04932 char *keyn; 04933 char tmpkey[256]; 04934 char *stringp=NULL; 04935 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 04936 stringp=tmpkey; 04937 keyn = strsep(&stringp, ":"); 04938 while(keyn) { 04939 key = ast_key_get(keyn, AST_KEY_PUBLIC); 04940 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 04941 res = 0; 04942 break; 04943 } else if (!key) 04944 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 04945 keyn = strsep(&stringp, ":"); 04946 } 04947 } else if (p->authmethods & IAX_AUTH_MD5) { 04948 struct MD5Context md5; 04949 unsigned char digest[16]; 04950 char *tmppw, *stringp; 04951 04952 tmppw = ast_strdupa(p->secret); 04953 stringp = tmppw; 04954 while((tmppw = strsep(&stringp, ";"))) { 04955 MD5Init(&md5); 04956 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 04957 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 04958 MD5Final(digest, &md5); 04959 /* If they support md5, authenticate with it. */ 04960 for (x=0;x<16;x++) 04961 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 04962 if (!strcasecmp(requeststr, md5secret)) { 04963 res = 0; 04964 break; 04965 } 04966 } 04967 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 04968 if (!strcmp(secret, p->secret)) 04969 res = 0; 04970 } 04971 return res; 04972 }
| static int auto_congest | ( | void * | data | ) | [static] |
Definition at line 2724 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), and sip_call().
02725 { 02726 #ifdef SCHED_MULTITHREADED 02727 if (schedule_action(__auto_congest, data)) 02728 #endif 02729 __auto_congest(data); 02730 return 0; 02731 }
| static int auto_hangup | ( | void * | data | ) | [static] |
Definition at line 5859 of file chan_iax2.c.
References __auto_hangup(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::autoid, iaxs, iaxsl, and schedule_action.
Referenced by iax2_dprequest(), and iax2_provision().
05860 { 05861 int callno = (int)(long)(data); 05862 ast_mutex_lock(&iaxsl[callno]); 05863 if (iaxs[callno]) { 05864 iaxs[callno]->autoid = -1; 05865 } 05866 ast_mutex_unlock(&iaxsl[callno]); 05867 #ifdef SCHED_MULTITHREADED 05868 if (schedule_action(__auto_hangup, data)) 05869 #endif 05870 __auto_hangup(data); 05871 return 0; 05872 }
| static struct iax2_context* build_context | ( | char * | context | ) | [static] |
Definition at line 8247 of file chan_iax2.c.
References ast_calloc.
Referenced by build_user().
08248 { 08249 struct iax2_context *con; 08250 08251 if ((con = ast_calloc(1, sizeof(*con)))) 08252 ast_copy_string(con->context, context, sizeof(con->context)); 08253 08254 return con; 08255 }
| static void build_enc_keys | ( | const unsigned char * | digest, | |
| aes_encrypt_ctx * | ecx, | |||
| aes_decrypt_ctx * | dcx | |||
| ) | [static] |
Definition at line 3658 of file chan_iax2.c.
References aes_decrypt_key128(), and aes_encrypt_key128().
Referenced by authenticate(), and decrypt_frame().
03659 { 03660 aes_encrypt_key128(digest, ecx); 03661 aes_decrypt_key128(digest, dcx); 03662 }
| static struct iax2_peer * build_peer | ( | const char * | name, | |
| struct ast_variable * | v, | |||
| struct ast_variable * | alt, | |||
| int | temponly | |||
| ) | [static] |
Create peer structure based on configuration.
Definition at line 8372 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_clear_flag, ast_copy_flags, ast_dnsmgr_lookup(), ast_free_ha(), ast_get_ip(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_parse_allow_disallow(), ast_sched_del(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_string_field_free_pools, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), 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, free, get_auth_methods(), get_encrypt_methods(), globalflags, iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, ast_variable::lineno, LOG_NOTICE, LOG_WARNING, mailbox, iax2_peer::mask, iax2_peer::maxms, ast_variable::name, ast_variable::next, peer_set_srcaddr(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax2_peer::prefs, prefs, sched, iax2_peer::smoothing, and ast_variable::value.
08373 { 08374 struct iax2_peer *peer = NULL; 08375 struct ast_ha *oldha = NULL; 08376 int maskfound=0; 08377 int found=0; 08378 int firstpass=1; 08379 08380 AST_LIST_LOCK(&peers); 08381 if (!temponly) { 08382 AST_LIST_TRAVERSE(&peers, peer, entry) { 08383 if (!strcmp(peer->name, name)) { 08384 if (!ast_test_flag(peer, IAX_DELME)) 08385 firstpass = 0; 08386 break; 08387 } 08388 } 08389 } else 08390 peer = NULL; 08391 if (peer) { 08392 found++; 08393 if (firstpass) { 08394 oldha = peer->ha; 08395 peer->ha = NULL; 08396 } 08397 AST_LIST_REMOVE(&peers, peer, entry); 08398 AST_LIST_UNLOCK(&peers); 08399 } else { 08400 AST_LIST_UNLOCK(&peers); 08401 if ((peer = ast_calloc(1, sizeof(*peer)))) { 08402 peer->expire = -1; 08403 peer->pokeexpire = -1; 08404 peer->sockfd = defaultsockfd; 08405 if (ast_string_field_init(peer, 32)) { 08406 free(peer); 08407 peer = NULL; 08408 } 08409 } 08410 } 08411 if (peer) { 08412 if (firstpass) { 08413 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08414 peer->encmethods = iax2_encryption; 08415 peer->adsi = adsi; 08416 ast_string_field_set(peer,secret,""); 08417 if (!found) { 08418 ast_string_field_set(peer, name, name); 08419 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 08420 peer->expiry = min_reg_expire; 08421 } 08422 peer->prefs = prefs; 08423 peer->capability = iax2_capability; 08424 peer->smoothing = 0; 08425 peer->pokefreqok = DEFAULT_FREQ_OK; 08426 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 08427 ast_string_field_set(peer,context,""); 08428 ast_string_field_set(peer,peercontext,""); 08429 ast_clear_flag(peer, IAX_HASCALLERID); 08430 ast_string_field_set(peer, cid_name, ""); 08431 ast_string_field_set(peer, cid_num, ""); 08432 } 08433 08434 if (!v) { 08435 v = alt; 08436 alt = NULL; 08437 } 08438 while(v) { 08439 if (!strcasecmp(v->name, "secret")) { 08440 ast_string_field_set(peer, secret, v->value); 08441 } else if (!strcasecmp(v->name, "mailbox")) { 08442 ast_string_field_set(peer, mailbox, v->value); 08443 } else if (!strcasecmp(v->name, "mohinterpret")) { 08444 ast_string_field_set(peer, mohinterpret, v->value); 08445 } else if (!strcasecmp(v->name, "mohsuggest")) { 08446 ast_string_field_set(peer, mohsuggest, v->value); 08447 } else if (!strcasecmp(v->name, "dbsecret")) { 08448 ast_string_field_set(peer, dbsecret, v->value); 08449 } else if (!strcasecmp(v->name, "trunk")) { 08450 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 08451 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) { 08452 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name); 08453 ast_clear_flag(peer, IAX_TRUNK); 08454 } 08455 } else if (!strcasecmp(v->name, "auth")) { 08456 peer->authmethods = get_auth_methods(v->value); 08457 } else if (!strcasecmp(v->name, "encryption")) { 08458 peer->encmethods = get_encrypt_methods(v->value); 08459 } else if (!strcasecmp(v->name, "notransfer")) { 08460 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 08461 ast_clear_flag(peer, IAX_TRANSFERMEDIA); 08462 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 08463 } else if (!strcasecmp(v->name, "transfer")) { 08464 if (!strcasecmp(v->value, "mediaonly")) { 08465 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 08466 } else if (ast_true(v->value)) { 08467 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 08468 } else 08469 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 08470 } else if (!strcasecmp(v->name, "jitterbuffer")) { 08471 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 08472 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 08473 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 08474 } else if (!strcasecmp(v->name, "host")) { 08475 if (!strcasecmp(v->value, "dynamic")) { 08476 /* They'll register with us */ 08477 ast_set_flag(peer, IAX_DYNAMIC); 08478 if (!found) { 08479 /* Initialize stuff iff we're not found, otherwise 08480 we keep going with what we had */ 08481 memset(&peer->addr.sin_addr, 0, 4); 08482 if (peer->addr.sin_port) { 08483 /* If we've already got a port, make it the default rather than absolute */ 08484 peer->defaddr.sin_port = peer->addr.sin_port; 08485 peer->addr.sin_port = 0; 08486 } 08487 } 08488 } else { 08489 /* Non-dynamic. Make sure we become that way if we're not */ 08490 if (peer->expire > -1) 08491 ast_sched_del(sched, peer->expire); 08492 peer->expire = -1; 08493 ast_clear_flag(peer, IAX_DYNAMIC); 08494 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) { 08495 ast_string_field_free_pools(peer); 08496 free(peer); 08497 return NULL; 08498 } 08499 if (!peer->addr.sin_port) 08500 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 08501 } 08502 if (!maskfound) 08503 inet_aton("255.255.255.255", &peer->mask); 08504 } else if (!strcasecmp(v->name, "defaultip")) { 08505 if (ast_get_ip(&peer->defaddr, v->value)) { 08506 ast_string_field_free_pools(peer); 08507 free(peer); 08508 return NULL; 08509 } 08510 } else if (!strcasecmp(v->name, "sourceaddress")) { 08511 peer_set_srcaddr(peer, v->value); 08512 } else if (!strcasecmp(v->name, "permit") || 08513 !strcasecmp(v->name, "deny")) { 08514 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 08515 } else if (!strcasecmp(v->name, "mask")) { 08516 maskfound++; 08517 inet_aton(v->value, &peer->mask); 08518 } else if (!strcasecmp(v->name, "context")) { 08519 ast_string_field_set(peer, context, v->value); 08520 } else if (!strcasecmp(v->name, "regexten")) { 08521 ast_string_field_set(peer, regexten, v->value); 08522 } else if (!strcasecmp(v->name, "peercontext")) { 08523 ast_string_field_set(peer, peercontext, v->value); 08524 } else if (!strcasecmp(v->name, "port")) { 08525 if (ast_test_flag(peer, IAX_DYNAMIC)) 08526 peer->defaddr.sin_port = htons(atoi(v->value)); 08527 else 08528 peer->addr.sin_port = htons(atoi(v->value)); 08529 } else if (!strcasecmp(v->name, "username")) { 08530 ast_string_field_set(peer, username, v->value); 08531 } else if (!strcasecmp(v->name, "allow")) { 08532 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 08533 } else if (!strcasecmp(v->name, "disallow")) { 08534 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 08535 } else if (!strcasecmp(v->name, "callerid")) { 08536 if (!ast_strlen_zero(v->value)) { 08537 char name2[80]; 08538 char num2[80]; 08539 ast_callerid_split(v->value, name2, 80, num2, 80); 08540 ast_string_field_set(peer, cid_name, name2); 08541 ast_string_field_set(peer, cid_num, num2); 08542 ast_set_flag(peer, IAX_HASCALLERID); 08543 } else { 08544 ast_clear_flag(peer, IAX_HASCALLERID); 08545 ast_string_field_set(peer, cid_name, ""); 08546 ast_string_field_set(peer, cid_num, ""); 08547 } 08548 } else if (!strcasecmp(v->name, "fullname")) { 08549 if (!ast_strlen_zero(v->value)) { 08550 ast_string_field_set(peer, cid_name, v->value); 08551 ast_set_flag(peer, IAX_HASCALLERID); 08552 } else { 08553 ast_string_field_set(peer, cid_name, ""); 08554 if (ast_strlen_zero(peer->cid_num)) 08555 ast_clear_flag(peer, IAX_HASCALLERID); 08556 } 08557 } else if (!strcasecmp(v->name, "cid_number")) { 08558 if (!ast_strlen_zero(v->value)) { 08559 ast_string_field_set(peer, cid_num, v->value); 08560 ast_set_flag(peer, IAX_HASCALLERID); 08561 } else { 08562 ast_string_field_set(peer, cid_num, ""); 08563 if (ast_strlen_zero(peer->cid_name)) 08564 ast_clear_flag(peer, IAX_HASCALLERID); 08565 } 08566 } else if (!strcasecmp(v->name, "sendani")) { 08567 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 08568 } else if (!strcasecmp(v->name, "inkeys")) { 08569 ast_string_field_set(peer, inkeys, v->value); 08570 } else if (!strcasecmp(v->name, "outkey")) { 08571 ast_string_field_set(peer, outkey, v->value); 08572 } else if (!strcasecmp(v->name, "qualify")) { 08573 if (!strcasecmp(v->value, "no")) { 08574 peer->maxms = 0; 08575 } else if (!strcasecmp(v->value, "yes")) { 08576 peer->maxms = DEFAULT_MAXMS; 08577 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 08578 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); 08579 peer->maxms = 0; 08580 } 08581 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 08582 peer->smoothing = ast_true(v->value); 08583 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 08584 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) { 08585 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); 08586 } 08587 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 08588 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) { 08589 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); 08590 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 08591 } else if (!strcasecmp(v->name, "timezone")) { 08592 ast_string_field_set(peer, zonetag, v->value); 08593 } else if (!strcasecmp(v->name, "adsi")) { 08594 peer->adsi = ast_true(v->value); 08595 }/* else if (strcasecmp(v->name,"type")) */ 08596 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 08597 v = v->next; 08598 if (!v) { 08599 v = alt; 08600 alt = NULL; 08601 } 08602 } 08603 if (!peer->authmethods) 08604 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 08605 ast_clear_flag(peer, IAX_DELME); 08606 /* Make sure these are IPv4 addresses */ 08607 peer->addr.sin_family = AF_INET; 08608 } 08609 if (oldha) 08610 ast_free_ha(oldha); 08611 return peer; 08612 }
| static struct iax2_user * build_user | ( | const char * | name, | |
| struct ast_variable * | v, | |||
| struct ast_variable * | alt, | |||
| int | temponly | |||
| ) | [static] |
Create in-memory user structure from configuration.
Definition at line 8615 of file chan_iax2.c.
References iax2_user::adsi, iax2_user::amaflags, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_free_ha(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_strdupa, ast_string_field_build, ast_string_field_free_pools, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), iax2_user::authmethods, build_context(), iax2_user::capability, cid_name, cid_num, iax2_user::contexts, iax2_user::curauthreq, iax2_user::encmethods, format, free, free_context(), get_auth_methods(), get_encrypt_methods(), globalflags, iax2_user::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DELME, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, ast_variable::lineno, LOG_NOTICE, LOG_WARNING, iax2_user::maxauthreq, ast_variable::name, ast_variable::next, iax2_user::prefs, prefs, ast_variable::value, and iax2_user::vars.
08616 { 08617 struct iax2_user *user = NULL; 08618 struct iax2_context *con, *conl = NULL; 08619 struct ast_ha *oldha = NULL; 08620 struct iax2_context *oldcon = NULL; 08621 int format; 08622 int firstpass=1; 08623 int oldcurauthreq = 0; 08624 char *varname = NULL, *varval = NULL; 08625 struct ast_variable *tmpvar = NULL; 08626 08627 AST_LIST_LOCK(&users); 08628 if (!temponly) { 08629 AST_LIST_TRAVERSE(&users, user, entry) { 08630 if (!strcmp(user->name, name)) { 08631 if (!ast_test_flag(user, IAX_DELME)) 08632 firstpass = 0; 08633 break; 08634 } 08635 } 08636 } else 08637 user = NULL; 08638 08639 if (user) { 08640 if (firstpass) { 08641 oldcurauthreq = user->curauthreq; 08642 oldha = user->ha; 08643 oldcon = user->contexts; 08644 user->ha = NULL; 08645 user->contexts = NULL; 08646 } 08647 /* Already in the list, remove it and it will be added back (or FREE'd) */ 08648 AST_LIST_REMOVE(&users, user, entry); 08649 AST_LIST_UNLOCK(&users); 08650 } else { 08651 AST_LIST_UNLOCK(&users); 08652 /* This is going to memset'd to 0 in the next block */ 08653 user = ast_calloc(sizeof(*user),1); 08654 } 08655 08656 if (user) { 08657 if (firstpass) { 08658 ast_string_field_free_pools(user); 08659 memset(user, 0, sizeof(struct iax2_user)); 08660 if (ast_string_field_init(user, 32)) { 08661 free(user); 08662 user = NULL; 08663 } 08664 user->maxauthreq = maxauthreq; 08665 user->curauthreq = oldcurauthreq; 08666 user->prefs = prefs; 08667 user->capability = iax2_capability; 08668 user->encmethods = iax2_encryption; 08669 user->adsi = adsi; 08670 ast_string_field_set(user, name, name); 08671 ast_string_field_set(user, language, language); 08672 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 08673 ast_clear_flag(user, IAX_HASCALLERID); 08674 ast_string_field_set(user, cid_name, ""); 08675 ast_string_field_set(user, cid_num, ""); 08676 } 08677 if (!v) { 08678 v = alt; 08679 alt = NULL; 08680 } 08681 while(v) { 08682 if (!strcasecmp(v->name, "context")) { 08683 con = build_context(v->value); 08684 if (con) { 08685 if (conl) 08686 conl->next = con; 08687 else 08688 user->contexts = con; 08689 conl = con; 08690 } 08691 } else if (!strcasecmp(v->name, "permit") || 08692 !strcasecmp(v->name, "deny")) { 08693 user->ha = ast_append_ha(v->name, v->value, user->ha); 08694 } else if (!strcasecmp(v->name, "setvar")) { 08695 varname = ast_strdupa(v->value); 08696 if (varname && (varval = strchr(varname,'='))) { 08697 *varval = '\0'; 08698 varval++; 08699 if((tmpvar = ast_variable_new(varname, varval))) { 08700 tmpvar->next = user->vars; 08701 user->vars = tmpvar; 08702 } 08703 } 08704 } else if (!strcasecmp(v->name, "allow")) { 08705 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 08706 } else if (!strcasecmp(v->name, "disallow")) { 08707 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 08708 } else if (!strcasecmp(v->name, "trunk")) { 08709 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 08710 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) { 08711 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name); 08712 ast_clear_flag(user, IAX_TRUNK); 08713 } 08714 } else if (!strcasecmp(v->name, "auth")) { 08715 user->authmethods = get_auth_methods(v->value); 08716 } else if (!strcasecmp(v->name, "encryption")) { 08717 user->encmethods = get_encrypt_methods(v->value); 08718 } else if (!strcasecmp(v->name, "notransfer")) { 08719 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 08720 ast_clear_flag(user, IAX_TRANSFERMEDIA); 08721 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 08722 } else if (!strcasecmp(v->name, "transfer")) { 08723 if (!strcasecmp(v->value, "mediaonly")) { 08724 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 08725 } else if (ast_true(v->value)) { 08726 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 08727 } else 08728 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 08729 } else if (!strcasecmp(v->name, "codecpriority")) { 08730 if(!strcasecmp(v->value, "caller")) 08731 ast_set_flag(user, IAX_CODEC_USER_FIRST); 08732 else if(!strcasecmp(v->value, "disabled")) 08733 ast_set_flag(user, IAX_CODEC_NOPREFS); 08734 else if(!strcasecmp(v->value, "reqonly")) { 08735 ast_set_flag(user, IAX_CODEC_NOCAP); 08736 ast_set_flag(user, IAX_CODEC_NOPREFS); 08737 } 08738 } else if (!strcasecmp(v->name, "jitterbuffer")) { 08739 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 08740 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 08741 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 08742 } else if (!strcasecmp(v->name, "dbsecret")) { 08743 ast_string_field_set(user, dbsecret, v->value); 08744 } else if (!strcasecmp(v->name, "secret")) { 08745 if (!ast_strlen_zero(user->secret)) { 08746 char *old = ast_strdupa(user->secret); 08747 08748 ast_string_field_build(user, secret, "%s;%s", old, v->value); 08749 } else 08750 ast_string_field_set(user, secret, v->value); 08751 } else if (!strcasecmp(v->name, "callerid")) { 08752 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 08753 char name2[80]; 08754 char num2[80]; 08755 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 08756 ast_string_field_set(user, cid_name, name2); 08757 ast_string_field_set(user, cid_num, num2); 08758 ast_set_flag(user, IAX_HASCALLERID); 08759 } else { 08760 ast_clear_flag(user, IAX_HASCALLERID); 08761 ast_string_field_set(user, cid_name, ""); 08762 ast_string_field_set(user, cid_num, ""); 08763 } 08764 } else if (!strcasecmp(v->name, "fullname")) { 08765 if (!ast_strlen_zero(v->value)) { 08766 ast_string_field_set(user, cid_name, v->value); 08767 ast_set_flag(user, IAX_HASCALLERID); 08768 } else { 08769 ast_string_field_set(user, cid_name, ""); 08770 if (ast_strlen_zero(user->cid_num)) 08771 ast_clear_flag(user, IAX_HASCALLERID); 08772 } 08773 } else if (!strcasecmp(v->name, "cid_number")) { 08774 if (!ast_strlen_zero(v->value)) { 08775 ast_string_field_set(user, cid_num, v->value); 08776 ast_set_flag(user, IAX_HASCALLERID); 08777 } else { 08778 ast_string_field_set(user, cid_num, ""); 08779 if (ast_strlen_zero(user->cid_name)) 08780 ast_clear_flag(user, IAX_HASCALLERID); 08781 } 08782 } else if (!strcasecmp(v->name, "accountcode")) { 08783 ast_string_field_set(user, accountcode, v->value); 08784 } else if (!strcasecmp(v->name, "mohinterpret")) { 08785 ast_string_field_set(user, mohinterpret, v->value); 08786 } else if (!strcasecmp(v->name, "mohsuggest")) { 08787 ast_string_field_set(user, mohsuggest, v->value); 08788 } else if (!strcasecmp(v->name, "language")) { 08789 ast_string_field_set(user, language, v->value); 08790 } else if (!strcasecmp(v->name, "amaflags")) { 08791 format = ast_cdr_amaflags2int(v->value); 08792 if (format < 0) { 08793 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 08794 } else { 08795 user->amaflags = format; 08796 } 08797 } else if (!strcasecmp(v->name, "inkeys")) { 08798 ast_string_field_set(user, inkeys, v->value); 08799 } else if (!strcasecmp(v->name, "maxauthreq")) { 08800 user->maxauthreq = atoi(v->value); 08801 if (user->maxauthreq < 0) 08802 user->maxauthreq = 0; 08803 } else if (!strcasecmp(v->name, "adsi")) { 08804 user->adsi = ast_true(v->value); 08805 }/* else if (strcasecmp(v->name,"type")) */ 08806 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 08807 v = v->next; 08808 if (!v) { 08809 v = alt; 08810 alt = NULL; 08811 } 08812 } 08813 if (!user->authmethods) { 08814 if (!ast_strlen_zero(user->secret)) { 08815 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 08816 if (!ast_strlen_zero(user->inkeys)) 08817 user->authmethods |= IAX_AUTH_RSA; 08818 } else if (!ast_strlen_zero(user->inkeys)) { 08819 user->authmethods = IAX_AUTH_RSA; 08820 } else { 08821 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 08822 } 08823 } 08824 ast_clear_flag(user, IAX_DELME); 08825 } 08826 if (oldha) 08827 ast_free_ha(oldha); 08828 if (oldcon) 08829 free_context(oldcon); 08830 return user; 08831 }
| static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 9355 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_strdupa, ast_string_field_set, chan_iax2_pvt::capability, create_addr(), find_callno(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_COMMAND_NEW, iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CAPABILITY, IAX_IE_FORMAT, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, iaxs, iaxsl, LOG_WARNING, NEW_FORCE, parse_dial_string(), and send_command().
Referenced by find_cache().
09356 { 09357 struct sockaddr_in sin; 09358 int x; 09359 int callno; 09360 struct iax_ie_data ied; 09361 struct create_addr_info cai; 09362 struct parsed_dial_string pds; 09363 char *tmpstr; 09364 09365 for (x=0; x<IAX_MAX_CALLS; x++) { 09366 /* Look for an *exact match* call. Once a call is negotiated, it can only 09367 look up entries for a single context */ 09368 if (!ast_mutex_trylock(&iaxsl[x])) { 09369 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 09370 return x; 09371 ast_mutex_unlock(&iaxsl[x]); 09372 } 09373 } 09374 09375 /* No match found, we need to create a new one */ 09376 09377 memset(&cai, 0, sizeof(cai)); 09378 memset(&ied, 0, sizeof(ied)); 09379 memset(&pds, 0, sizeof(pds)); 09380 09381 tmpstr = ast_strdupa(data); 09382 parse_dial_string(tmpstr, &pds); 09383 09384 /* Populate our address from the given */ 09385 if (create_addr(pds.peer, &sin, &cai)) 09386 return -1; 09387 09388 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n", 09389 pds.peer, pds.username, pds.password, pds.context); 09390 09391 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd); 09392 if (callno < 1) { 09393 ast_log(LOG_WARNING, "Unable to create call\n"); 09394 return -1; 09395 } 09396 09397 ast_mutex_lock(&iaxsl[callno]); 09398 ast_string_field_set(iaxs[callno], dproot, data); 09399 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 09400 09401 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 09402 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 09403 /* the string format is slightly different from a standard dial string, 09404 because the context appears in the 'exten' position 09405 */ 09406 if (pds.exten) 09407 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 09408 if (pds.username) 09409 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 09410 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 09411 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 09412 /* Keep password handy */ 09413 if (pds.password) 09414 ast_string_field_set(iaxs[callno], secret, pds.password); 09415 if (pds.key) 09416 ast_string_field_set(iaxs[callno], outkey, pds.key); 09417 /* Start the call going */ 09418 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 09419 09420 return callno; 09421 }
| static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
| unsigned int | offset | |||
| ) | [static] |
Definition at line 3528 of file chan_iax2.c.
References ast_log(), ast_random(), ast_tvsub(), chan_iax2_pvt::callno, option_debug, and chan_iax2_pvt::rxcore.
03529 { 03530 /* Returns where in "receive time" we are. That is, how many ms 03531 since we received (or would have received) the frame with timestamp 0 */ 03532 int ms; 03533 #ifdef IAXTESTS 03534 int jit; 03535 #endif /* IAXTESTS */ 03536 /* Setup rxcore if necessary */ 03537 if (ast_tvzero(p->rxcore)) { 03538 p->rxcore = ast_tvnow(); 03539 if (option_debug && iaxdebug) 03540 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 03541 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 03542 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 03543 #if 1 03544 if (option_debug && iaxdebug) 03545 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 03546 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 03547 #endif 03548 } 03549 03550 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 03551 #ifdef IAXTESTS 03552 if (test_jit) { 03553 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 03554 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 03555 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 03556 jit = -jit; 03557 ms += jit; 03558 } 03559 } 03560 if (test_late) { 03561 ms += test_late; 03562 test_late = 0; 03563 } 03564 #endif /* IAXTESTS */ 03565 return ms; 03566 }
| static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
| unsigned int | ts, | |||
| struct ast_frame * | f | |||
| ) | [static] |
Definition at line 3410 of file chan_iax2.c.
References AST_FRAME_CNG, AST_FRAME_IAX, AST_FRAME_VOICE, ast_log(), ast_tvadd(), ast_tvsub(), chan_iax2_pvt::callno, f, iaxs, chan_iax2_pvt::lastsent, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, chan_iax2_pvt::offset, option_debug, and chan_iax2_pvt::peercallno.
Referenced by iax2_send(), and socket_process().
03411 { 03412 int ms; 03413 int voice = 0; 03414 int genuine = 0; 03415 int adjust; 03416 struct timeval *delivery = NULL; 03417 03418 03419 /* What sort of frame do we have?: voice is self-explanatory 03420 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 03421 non-genuine frames are CONTROL frames [ringing etc], DTMF 03422 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 03423 the others need a timestamp slaved to the voice frames so that they go in sequence 03424 */ 03425 if (f) { 03426 if (f->frametype == AST_FRAME_VOICE) { 03427 voice = 1; 03428 delivery = &f->delivery; 03429 } else if (f->frametype == AST_FRAME_IAX) { 03430 genuine = 1; 03431 } else if (f->frametype == AST_FRAME_CNG) { 03432 p->notsilenttx = 0; 03433 } 03434 } 03435 if (ast_tvzero(p->offset)) { 03436 gettimeofday(&p->offset, NULL); 03437 /* Round to nearest 20ms for nice looking traces */ 03438 p->offset.tv_usec -= p->offset.tv_usec % 20000; 03439 } 03440 /* If the timestamp is specified, just send it as is */ 03441 if (ts) 03442 return ts; 03443 /* If we have a time that the frame arrived, always use it to make our timestamp */ 03444 if (delivery && !ast_tvzero(*delivery)) { 03445 ms = ast_tvdiff_ms(*delivery, p->offset); 03446 if (option_debug > 2 && iaxdebug) 03447 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 03448 } else { 03449 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 03450 if (ms < 0) 03451 ms = 0; 03452 if (voice) { 03453 /* On a voice frame, use predicted values if appropriate */ 03454 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 03455 /* Adjust our txcore, keeping voice and non-voice synchronized */ 03456 /* AN EXPLANATION: 03457 When we send voice, we usually send "calculated" timestamps worked out 03458 on the basis of the number of samples sent. When we send other frames, 03459 we usually send timestamps worked out from the real clock. 03460 The problem is that they can tend to drift out of step because the 03461 source channel's clock and our clock may not be exactly at the same rate. 03462 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 03463 for this call. Moving it adjusts timestamps for non-voice frames. 03464 We make the adjustment in the style of a moving average. Each time we 03465 adjust p->offset by 10% of the difference between our clock-derived 03466 timestamp and the predicted timestamp. That's why you see "10000" 03467 below even though IAX2 timestamps are in milliseconds. 03468 The use of a moving average avoids offset moving too radically. 03469 Generally, "adjust" roams back and forth around 0, with offset hardly 03470 changing at all. But if a consistent different starts to develop it 03471 will be eliminated over the course of 10 frames (200-300msecs) 03472 */ 03473 adjust = (ms - p->nextpred); 03474 if (adjust < 0) 03475 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 03476 else if (adjust > 0) 03477 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 03478 03479 if (!p->nextpred) { 03480 p->nextpred = ms; /*f->samples / 8;*/ 03481 if (p->nextpred <= p->lastsent) 03482 p->nextpred = p->lastsent + 3; 03483 } 03484 ms = p->nextpred; 03485 } else { 03486 /* in this case, just use the actual 03487 * time, since we're either way off 03488 * (shouldn't happen), or we're ending a 03489 * silent period -- and seed the next 03490 * predicted time. Also, round ms to the 03491 * next multiple of frame size (so our 03492 * silent periods are multiples of 03493 * frame size too) */ 03494 03495 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 03496 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 03497 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 03498 03499 if (f->samples >= 8) /* check to make sure we dont core dump */ 03500 { 03501 int diff = ms % (f->samples / 8); 03502 if (diff) 03503 ms += f->samples/8 - diff; 03504 } 03505 03506 p->nextpred = ms; 03507 p->notsilenttx = 1; 03508 } 03509 } else { 03510 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 03511 it's a genuine frame */ 03512 if (genuine) { 03513 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 03514 if (ms <= p->lastsent) 03515 ms = p->lastsent + 3; 03516 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 03517 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 03518 ms = p->lastsent + 3; 03519 } 03520 } 03521 } 03522 p->lastsent = ms; 03523 if (voice) 03524 p->nextpred = p->nextpred + f->samples / 8; 03525 return ms; 03526 }
| static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
| int | sampms, | |||
| struct timeval * | tv | |||
| ) | [static] |
Definition at line 3366 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().
03367 { 03368 unsigned long int mssincetx; /* unsigned to handle overflows */ 03369 long int ms, pred; 03370 03371 tpeer->trunkact = *tv; 03372 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime); 03373 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 03374 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 03375 tpeer->txtrunktime = *tv; 03376 tpeer->lastsent = 999999; 03377 } 03378 /* Update last transmit time now */ 03379 tpeer->lasttxtime = *tv; 03380 03381 /* Calculate ms offset */ 03382 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime); 03383 /* Predict from last value */ 03384 pred = tpeer->lastsent + sampms; 03385 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 03386 ms = pred; 03387 03388 /* We never send the same timestamp twice, so fudge a little if we must */ 03389 if (ms == tpeer->lastsent) 03390 ms = tpeer->lastsent + 1; 03391 tpeer->lastsent = ms; 03392 return ms; 03393 }
| static int check_access | ( | int | callno, | |
| struct sockaddr_in * | sin, | |||
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 4614 of file chan_iax2.c.
References iax2_user::adsi, chan_iax2_pvt::adsi, chan_iax2_pvt::amaflags, iax2_user::amaflags, apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, ast_set2_flag, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_variable_new(), iax2_user::authmethods, chan_iax2_pvt::authmethods, chan_iax2_pvt::calling_pres, chan_iax2_pvt::calling_tns, chan_iax2_pvt::calling_ton, iax2_user::capability, chan_iax2_pvt::capability, cid_name, cid_num, iax2_context::context, iax2_user::contexts, destroy_user(), iax2_user::encmethods, chan_iax2_pvt::encmethods, exten, iax2_user::ha, iax2_getpeertrunk(), IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_MAXAUTHREQ, IAX_NOTRANSFER, IAX_PROTO_VERSION, IAX_TEMPONLY, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, ies, key(), LOG_WARNING, iax2_user::maxauthreq, ast_variable::name, ast_variable::next, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_user::prefs, chan_iax2_pvt::prefs, prefs, realtime_user(), ast_variable::value, chan_iax2_pvt::vars, and iax2_user::vars.
Referenced by socket_process().
04615 { 04616 /* Start pessimistic */ 04617 int res = -1; 04618 int version = 2; 04619 struct iax2_user *user = NULL, *best = NULL; 04620 int bestscore = 0; 04621 int gotcapability = 0; 04622 struct ast_variable *v = NULL, *tmpvar = NULL; 04623 04624 if (!iaxs[callno]) 04625 return res; 04626 if (ies->called_number) 04627 ast_string_field_set(iaxs[callno], exten, ies->called_number); 04628 if (ies->calling_number) { 04629 ast_shrink_phone_number(ies->calling_number); 04630 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 04631 } 04632 if (ies->calling_name) 04633 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 04634 if (ies->calling_ani) 04635 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 04636 if (ies->dnid) 04637 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 04638 if (ies->rdnis) 04639 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 04640 if (ies->called_context) 04641 ast_string_field_set(iaxs[callno], context, ies->called_context); 04642 if (ies->language) 04643 ast_string_field_set(iaxs[callno], language, ies->language); 04644 if (ies->username) 04645 ast_string_field_set(iaxs[callno], username, ies->username); 04646 if (ies->calling_ton > -1) 04647 iaxs[callno]->calling_ton = ies->calling_ton; 04648 if (ies->calling_tns > -1) 04649 iaxs[callno]->calling_tns = ies->calling_tns; 04650 if (ies->calling_pres > -1) 04651 iaxs[callno]->calling_pres = ies->calling_pres; 04652 if (ies->format) 04653 iaxs[callno]->peerformat = ies->format; 04654 if (ies->adsicpe) 04655 iaxs[callno]->peeradsicpe = ies->adsicpe; 04656 if (ies->capability) { 04657 gotcapability = 1; 04658 iaxs[callno]->peercapability = ies->capability; 04659 } 04660 if (ies->version) 04661 version = ies->version; 04662 04663 /* Use provided preferences until told otherwise for actual preferences */ 04664 if(ies->codec_prefs) { 04665 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 04666 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 04667 } 04668 04669 if (!gotcapability) 04670 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 04671 if (version > IAX_PROTO_VERSION) { 04672 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 04673 ast_inet_ntoa(sin->sin_addr), version); 04674 return res; 04675 } 04676 /* Search the userlist for a compatible entry, and fill in the rest */ 04677 AST_LIST_LOCK(&users); 04678 AST_LIST_TRAVERSE(&users, user, entry) { 04679 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 04680 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 04681 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 04682 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 04683 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 04684 if (!ast_strlen_zero(iaxs[callno]->username)) { 04685 /* Exact match, stop right now. */ 04686 best = user; 04687 break; 04688 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->inkeys)) { 04689 /* No required authentication */ 04690 if (user->ha) { 04691 /* There was host authentication and we passed, bonus! */ 04692 if (bestscore < 4) { 04693 bestscore = 4; 04694 best = user; 04695 } 04696 } else { 04697 /* No host access, but no secret, either, not bad */ 04698 if (bestscore < 3) { 04699 bestscore = 3; 04700 best = user; 04701 } 04702 } 04703 } else { 04704 if (user->ha) { 04705 /* Authentication, but host access too, eh, it's something.. */ 04706 if (bestscore < 2) { 04707 bestscore = 2; 04708 best = user; 04709 } 04710 } else { 04711 /* Authentication and no host access... This is our baseline */ 04712 if (bestscore < 1) { 04713 bestscore = 1; 04714 best = user; 04715 } 04716 } 04717 } 04718 } 04719 } 04720 AST_LIST_UNLOCK(&users); 04721 user = best; 04722 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 04723 user = realtime_user(iaxs[callno]->username); 04724 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 04725 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 04726 destroy_user(user); 04727 user = NULL; 04728 } 04729 } 04730 if (user) { 04731 /* We found our match (use the first) */ 04732 /* copy vars */ 04733 for (v = user->vars ; v ; v = v->next) { 04734 if((tmpvar = ast_variable_new(v->name, v->value))) { 04735 tmpvar->next = iaxs[callno]->vars; 04736 iaxs[callno]->vars = tmpvar; 04737 } 04738 } 04739 /* If a max AUTHREQ restriction is in place, activate it */ 04740 if (user->maxauthreq > 0) 04741 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ); 04742 iaxs[callno]->prefs = user->prefs; 04743 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST); 04744 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS); 04745 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP); 04746 iaxs[callno]->encmethods = user->encmethods; 04747 /* Store the requested username if not specified */ 04748 if (ast_strlen_zero(iaxs[callno]->username)) 04749 ast_string_field_set(iaxs[callno], username, user->name); 04750 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 04751 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 04752 iaxs[callno]->capability = user->capability; 04753 /* And use the default context */ 04754 if (ast_strlen_zero(iaxs[callno]->context)) { 04755 if (user->contexts) 04756 ast_string_field_set(iaxs[callno], context, user->contexts->context); 04757 else 04758 ast_string_field_set(iaxs[callno], context, context); 04759 } 04760 /* And any input keys */ 04761 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 04762 /* And the permitted authentication methods */ 04763 iaxs[callno]->authmethods = user->authmethods; 04764 iaxs[callno]->adsi = user->adsi; 04765 /* If they have callerid, override the given caller id. Always store the ANI */ 04766 if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) { 04767 if (ast_test_flag(user, IAX_HASCALLERID)) { 04768 iaxs[callno]->calling_tns = 0; 04769 iaxs[callno]->calling_ton = 0; 04770 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 04771 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 04772 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 04773 } 04774 if (ast_strlen_zero(iaxs[callno]->ani)) 04775 ast_string_field_set(iaxs[callno], ani, user->cid_num); 04776 } else { 04777 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 04778 } 04779 if (!ast_strlen_zero(user->accountcode)) 04780 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 04781 if (!ast_strlen_zero(user->mohinterpret)) 04782 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 04783 if (!ast_strlen_zero(user->mohsuggest)) 04784 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 04785 if (user->amaflags) 04786 iaxs[callno]->amaflags = user->amaflags; 04787 if (!ast_strlen_zero(user->language)) 04788 ast_string_field_set(iaxs[callno], language, user->language); 04789 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 04790 /* Keep this check last */ 04791 if (!ast_strlen_zero(user->dbsecret)) { 04792 char *family, *key=NULL; 04793 char buf[80]; 04794 family = ast_strdupa(user->dbsecret); 04795 key = strchr(family, '/'); 04796 if (key) { 04797 *key = '\0'; 04798 key++; 04799 } 04800 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 04801 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 04802 else 04803 ast_string_field_set(iaxs[callno], secret, buf); 04804 } else 04805 ast_string_field_set(iaxs[callno], secret, user->secret); 04806 if (ast_test_flag(user, IAX_TEMPONLY)) 04807 destroy_user(user); 04808 res = 0; 04809 } 04810 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 04811 return res; 04812 }
| static int check_provisioning | ( | struct sockaddr_in * | sin, | |
| int | sockfd, | |||
| char * | si, | |||
| unsigned int | ver | |||
| ) | [static] |
Definition at line 6209 of file chan_iax2.c.
References ast_log(), iax2_provision(), iax_provision_version(), and option_debug.
Referenced by socket_process().
06210 { 06211 unsigned int ourver; 06212 char rsi[80]; 06213 snprintf(rsi, sizeof(rsi), "si-%s", si); 06214 if (iax_provision_version(&ourver, rsi, 1)) 06215 return 0; 06216 if (option_debug) 06217 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 06218 if (ourver != ver) 06219 iax2_provision(sin, sockfd, NULL, rsi, 1); 06220 return 0; 06221 }
| static int check_srcaddr | ( | struct sockaddr * | sa, | |
| socklen_t | salen | |||
| ) | [static] |
Check if address can be used as packet source.
Definition at line 8273 of file chan_iax2.c.
References ast_log(), and LOG_ERROR.
Referenced by peer_set_srcaddr().
08274 { 08275 int sd; 08276 int res; 08277 08278 sd = socket(AF_INET, SOCK_DGRAM, 0); 08279 if (sd < 0) { 08280 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 08281 return -1; 08282 } 08283 08284 res = bind(sd, sa, salen); 08285 if (res < 0) { 08286 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno)); 08287 close(sd); 08288 return 1; 08289 } 08290 08291 close(sd); 08292 return 0; 08293 }
| static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 5279 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_UNKNOWN, iax2_dpcache::callno, chan_iax2_pvt::dpentries, iax2_dpcache::expiry, iax2_dpcache::exten, exten, iax2_dpcache::flags, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, ies, iax2_dpcache::orig, iax2_dpcache::peer, and iax2_dpcache::waiters.
Referenced by socket_process().
05280 { 05281 char exten[256] = ""; 05282 int status = CACHE_FLAG_UNKNOWN; 05283 int expiry = iaxdefaultdpcache; 05284 int x; 05285 int matchmore = 0; 05286 struct iax2_dpcache *dp, *prev; 05287 05288 if (ies->called_number) 05289 ast_copy_string(exten, ies->called_number, sizeof(exten)); 05290 05291 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 05292 status = CACHE_FLAG_EXISTS; 05293 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 05294 status = CACHE_FLAG_CANEXIST; 05295 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 05296 status = CACHE_FLAG_NONEXISTENT; 05297 05298 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) { 05299 /* Don't really do anything with this */ 05300 } 05301 if (ies->refresh) 05302 expiry = ies->refresh; 05303 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 05304 matchmore = CACHE_FLAG_MATCHMORE; 05305 ast_mutex_lock(&dpcache_lock); 05306 prev = NULL; 05307 dp = pvt->dpentries; 05308 while(dp) { 05309 if (!strcmp(dp->exten, exten)) { 05310 /* Let them go */ 05311 if (prev) 05312 prev->peer = dp->peer; 05313 else 05314 pvt->dpentries = dp->peer; 05315 dp->peer = NULL; 05316 dp->callno = 0; 05317 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 05318 if (dp->flags & CACHE_FLAG_PENDING) { 05319 dp->flags &= ~CACHE_FLAG_PENDING; 05320 dp->flags |= status; 05321 dp->flags |= matchmore; 05322 } 05323 /* Wake up waiters */ 05324 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 05325 if (dp->waiters[x] > -1) 05326 write(dp->waiters[x], "asdf", 4); 05327 } 05328 prev = dp; 05329 dp = dp->peer; 05330 } 05331 ast_mutex_unlock(&dpcache_lock); 05332 return 0; 05333 }
| static char* complete_iax2_show_peer | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 2078 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strdup.
02079 { 02080 int which = 0; 02081 struct iax2_peer *p = NULL; 02082 char *res = NULL; 02083 int wordlen = strlen(word); 02084 02085 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */ 02086 if (pos == 3) { 02087 AST_LIST_LOCK(&peers); 02088 AST_LIST_TRAVERSE(&peers, p, entry) { 02089 if (!strncasecmp(p->name, word, wordlen) && ++which > state) { 02090 res = ast_strdup(p->name); 02091 break; 02092 } 02093 } 02094 AST_LIST_UNLOCK(&peers); 02095 } 02096 02097 return res; 02098 }
| static int complete_transfer | ( | int | callno, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 5335 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), iax_frame::callno, jb_frame::data, DEFAULT_RETRY_TIME, iax2_frame_free(), iaxq, iaxs, ies, chan_iax2_pvt::iseqno, chan_iax2_pvt::jb, jb_getall(), JB_OK, jb_reset(), chan_iax2_pvt::lag, chan_iax2_pvt::last, chan_iax2_pvt::lastsent, LOG_WARNING, chan_iax2_pvt::nextpred, chan_iax2_pvt::offset, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, iax_frame::retries, chan_iax2_pvt::rseqno, chan_iax2_pvt::rxcore, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, TRANSFER_NONE, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, chan_iax2_pvt::videoformat, and chan_iax2_pvt::voiceformat.
Referenced by socket_process().
05336 { 05337 int peercallno = 0; 05338 struct chan_iax2_pvt *pvt = iaxs[callno]; 05339 struct iax_frame *cur; 05340 jb_frame frame; 05341 05342 if (ies->callno) 05343 peercallno = ies->callno; 05344 05345 if (peercallno < 1) { 05346 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05347 return -1; 05348 } 05349 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 05350 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 05351 /* Reset sequence numbers */ 05352 pvt->oseqno = 0; 05353 pvt->rseqno = 0; 05354 pvt->iseqno = 0; 05355 pvt->aseqno = 0; 05356 pvt->peercallno = peercallno; 05357 pvt->transferring = TRANSFER_NONE; 05358 pvt->svoiceformat = -1; 05359 pvt->voiceformat = 0; 05360 pvt->svideoformat = -1; 05361 pvt->videoformat = 0; 05362 pvt->transfercallno = -1; 05363 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 05364 memset(&pvt->offset, 0, sizeof(pvt->offset)); 05365 /* reset jitterbuffer */ 05366 while(jb_getall(pvt->jb,&frame) == JB_OK) 05367 iax2_frame_free(frame.data); 05368 jb_reset(pvt->jb); 05369 pvt->lag = 0; 05370 pvt->last = 0; 05371 pvt->lastsent = 0; 05372 pvt->nextpred = 0; 05373 pvt->pingtime = DEFAULT_RETRY_TIME; 05374 AST_LIST_LOCK(&iaxq.queue); 05375 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 05376 /* We must cancel any packets that would have been transmitted 05377 because now we're talking to someone new. It's okay, they 05378 were transmitted to someone that didn't care anyway. */ 05379 if (callno == cur->callno) 05380 cur->retries = -1; 05381 } 05382 AST_LIST_UNLOCK(&iaxq.queue); 05383 return 0; 05384 }
| static unsigned char compress_subclass | ( | int | subclass | ) | [static] |
Definition at line 969 of file chan_iax2.c.
References ast_log(), IAX_FLAG_SC_LOG, IAX_MAX_SHIFT, and LOG_WARNING.
Referenced by iax2_send(), and raw_hangup().
00970 { 00971 int x; 00972 int power=-1; 00973 /* If it's 128 or smaller, just return it */ 00974 if (subclass < IAX_FLAG_SC_LOG) 00975 return subclass; 00976 /* Otherwise find its power */ 00977 for (x = 0; x < IAX_MAX_SHIFT; x++) { 00978 if (subclass & (1 << x)) { 00979 if (power > -1) { 00980 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 00981 return 0; 00982 } else 00983 power = x; 00984 } 00985 } 00986 return power | IAX_FLAG_SC_LOG; 00987 }
| static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ie_data * | iep | |||
| ) | [static] |
Definition at line 6223 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().
06224 { 06225 jb_info stats; 06226 jb_getinfo(pvt->jb, &stats); 06227 06228 memset(iep, 0, sizeof(*iep)); 06229 06230 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 06231 if(stats.frames_in == 0) stats.frames_in = 1; 06232 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 06233 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 06234 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 06235 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 06236 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 06237 }
| static int create_addr | ( | const char * | peername, | |
| struct sockaddr_in * | sin, | |||
| struct create_addr_info * | cai | |||
| ) | [static] |
Definition at line 2622 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, create_addr_info::adsi, ahp, ast_clear_flag, ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_gethostbyname(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, iax2_peer::capability, create_addr_info::capability, create_addr_info::context, iax2_peer::defaddr, destroy_peer(), iax2_peer::encmethods, create_addr_info::encmethods, find_peer(), create_addr_info::found, hp, IAX_DEFAULT_PORTNO, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TEMPONLY, 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, 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.
02623 { 02624 struct ast_hostent ahp; 02625 struct hostent *hp; 02626 struct iax2_peer *peer; 02627 02628 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 02629 cai->sockfd = defaultsockfd; 02630 cai->maxtime = 0; 02631 sin->sin_family = AF_INET; 02632 02633 if (!(peer = find_peer(peername, 1))) { 02634 cai->found = 0; 02635 02636 hp = ast_gethostbyname(peername, &ahp); 02637 if (hp) { 02638 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 02639 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 02640 /* use global iax prefs for unknown peer/user */ 02641 ast_codec_pref_convert(&prefs, cai->prefs, sizeof(cai->prefs), 1); 02642 return 0; 02643 } else { 02644 ast_log(LOG_WARNING, "No such host: %s\n", peername); 02645 return -1; 02646 } 02647 } 02648 02649 cai->found = 1; 02650 02651 /* if the peer has no address (current or default), return failure */ 02652 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) { 02653 if (ast_test_flag(peer, IAX_TEMPONLY)) 02654 destroy_peer(peer); 02655 return -1; 02656 } 02657 02658 /* if the peer is being monitored and is currently unreachable, return failure */ 02659 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) { 02660 if (ast_test_flag(peer, IAX_TEMPONLY)) 02661 destroy_peer(peer); 02662 return -1; 02663 } 02664 02665 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 02666 cai->maxtime = peer->maxms; 02667 cai->capability = peer->capability; 02668 cai->encmethods = peer->encmethods; 02669 cai->sockfd = peer->sockfd; 02670 cai->adsi = peer->adsi; 02671 ast_codec_pref_convert(&peer->prefs, cai->prefs, sizeof(cai->prefs), 1); 02672 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 02673 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 02674 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 02675 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 02676 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 02677 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 02678 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 02679 if (ast_strlen_zero(peer->dbsecret)) { 02680 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 02681 } else { 02682 char *family; 02683 char *key = NULL; 02684 02685 family = ast_strdupa(peer->dbsecret); 02686 key = strchr(family, '/'); 02687 if (key) 02688 *key++ = '\0'; 02689 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 02690 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 02691 if (ast_test_flag(peer, IAX_TEMPONLY)) 02692 destroy_peer(peer); 02693 return -1; 02694 } 02695 } 02696 02697 if (peer->addr.sin_addr.s_addr) { 02698 sin->sin_addr = peer->addr.sin_addr; 02699 sin->sin_port = peer->addr.sin_port; 02700 } else { 02701 sin->sin_addr = peer->defaddr.sin_addr; 02702 sin->sin_port = peer->defaddr.sin_port; 02703 } 02704 02705 if (ast_test_flag(peer, IAX_TEMPONLY)) 02706 destroy_peer(peer); 02707 02708 return 0; 02709 }
| static int decode_frame | ( | aes_decrypt_ctx * | dcx, | |
| struct ast_iax2_full_hdr * | fh, | |||
| struct ast_frame * | f, | |||
| int * | datalen | |||
| ) | [static] |
Definition at line 3712 of file chan_iax2.c.
References AST_FRAME_VIDEO, ast_log(), ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, f, IAX_FLAG_FULL, memcpy_decrypt(), option_debug, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::type, and uncompress_subclass().
Referenced by decrypt_frame().
03713 { 03714 int padding; 03715 unsigned char *workspace; 03716 03717 workspace = alloca(*datalen); 03718 memset(f, 0, sizeof(*f)); 03719 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 03720 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 03721 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 03722 return -1; 03723 /* Decrypt */ 03724 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 03725 03726 padding = 16 + (workspace[15] & 0xf); 03727 if (option_debug && iaxdebug) 03728 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 03729 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 03730 return -1; 03731 03732 *datalen -= padding; 03733 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 03734 f->frametype = fh->type; 03735 if (f->frametype == AST_FRAME_VIDEO) { 03736 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 03737 } else { 03738 f->subclass = uncompress_subclass(fh->csub); 03739 } 03740 } else { 03741 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 03742 if (option_debug && iaxdebug) 03743 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen); 03744 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 03745 return -1; 03746 /* Decrypt */ 03747 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 03748 padding = 16 + (workspace[15] & 0x0f); 03749 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 03750 return -1; 03751 *datalen -= padding; 03752 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 03753 } 03754 return 0; 03755 }
| static int decrypt_frame | ( | int | callno, | |
| struct ast_iax2_full_hdr * | fh, | |||
| struct ast_frame * | f, | |||
| int * | datalen | |||
| ) | [static] |
Definition at line 3798 of file chan_iax2.c.
References ast_set_flag, ast_strdupa, ast_test_flag, build_enc_keys(), decode_frame(), f, IAX_KEYPOPULATED, iaxs, md5(), MD5Final(), MD5Init(), MD5Update(), and strsep().
Referenced by socket_process().
03799 { 03800 int res=-1; 03801 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 03802 /* Search for possible keys, given secrets */ 03803 struct MD5Context md5; 03804 unsigned char digest[16]; 03805 char *tmppw, *stringp; 03806 03807 tmppw = ast_strdupa(iaxs[callno]->secret); 03808 stringp = tmppw; 03809 while ((tmppw = strsep(&stringp, ";"))) { 03810 MD5Init(&md5); 03811 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 03812 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 03813 MD5Final(digest, &md5); 03814 build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx); 03815 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 03816 if (!res) { 03817 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 03818 break; 03819 } 03820 } 03821 } else 03822 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 03823 return res; 03824 }
| static void delete_users | ( | void | ) | [static] |
Definition at line 8833 of file chan_iax2.c.
References ast_dnsmgr_release(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_set_flag, iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, free, iax2_destroy(), IAX_DELME, iaxs, iaxsl, chan_iax2_pvt::reg, and sched.
08834 { 08835 struct iax2_user *user; 08836 struct iax2_peer *peer; 08837 struct iax2_registry *reg; 08838 08839 AST_LIST_LOCK(&users); 08840 AST_LIST_TRAVERSE(&users, user, entry) 08841 ast_set_flag(user, IAX_DELME); 08842 AST_LIST_UNLOCK(&users); 08843 08844 AST_LIST_LOCK(®istrations); 08845 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 08846 if (reg->expire > -1) 08847 ast_sched_del(sched, reg->expire); 08848 if (reg->callno) { 08849 ast_mutex_lock(&iaxsl[reg->callno]); 08850 if (iaxs[reg->callno]) { 08851 iaxs[reg->callno]->reg = NULL; 08852 iax2_destroy(reg->callno); 08853 } 08854 ast_mutex_unlock(&iaxsl[reg->callno]); 08855 } 08856 if (reg->dnsmgr) 08857 ast_dnsmgr_release(reg->dnsmgr); 08858 free(reg); 08859 } 08860 AST_LIST_UNLOCK(®istrations); 08861 08862 AST_LIST_LOCK(&peers); 08863 AST_LIST_TRAVERSE(&peers, peer, entry) 08864 ast_set_flag(peer, IAX_DELME); 08865 AST_LIST_UNLOCK(&peers); 08866 }
| static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 1329 of file chan_iax2.c.
References ast_iax2_firmware_header::datalen, iax_firmware::fd, free, and iax_firmware::fwh.
Referenced by reload_firmware().
01330 { 01331 /* Close firmware */ 01332 if (cur->fwh) { 01333 munmap(cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 01334 } 01335 close(cur->fd); 01336 free(cur); 01337 }
| static void destroy_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 8896 of file chan_iax2.c.
References ast_dnsmgr_release(), ast_free_ha(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_string_field_free_pools, iax2_peer::callno, iax2_peer::dnsmgr, iax2_peer::expire, free, iax2_peer::ha, iax2_destroy(), iaxsl, iax2_peer::pokeexpire, register_peer_exten(), and sched.
Referenced by authenticate_reply(), create_addr(), iax2_devicestate(), iax2_getpeername(), iax2_show_peer(), prune_peers(), realtime_peer(), register_verify(), registry_authrequest(), and update_registry().
08897 { 08898 ast_free_ha(peer->ha); 08899 08900 /* Delete it, it needs to disappear */ 08901 if (peer->expire > -1) 08902 ast_sched_del(sched, peer->expire); 08903 if (peer->pokeexpire > -1) 08904 ast_sched_del(sched, peer->pokeexpire); 08905 if (peer->callno > 0) { 08906 ast_mutex_lock(&iaxsl[peer->callno]); 08907 iax2_destroy(peer->callno); 08908 ast_mutex_unlock(&iaxsl[peer->callno]); 08909 } 08910 08911 register_peer_exten(peer, 0); 08912 08913 if (peer->dnsmgr) 08914 ast_dnsmgr_release(peer->dnsmgr); 08915 08916 ast_string_field_free_pools(peer); 08917 08918 free(peer); 08919 }
| static void destroy_user | ( | struct iax2_user * | user | ) | [static] |
Definition at line 8868 of file chan_iax2.c.
References ast_free_ha(), ast_string_field_free_pools, ast_variables_destroy(), iax2_user::contexts, free, free_context(), iax2_user::ha, and iax2_user::vars.
Referenced by check_access(), and prune_users().
08869 { 08870 ast_free_ha(user->ha); 08871 free_context(user->contexts); 08872 if(user->vars) { 08873 ast_variables_destroy(user->vars); 08874 user->vars = NULL; 08875 } 08876 ast_string_field_free_pools(user); 08877 free(user); 08878 }
| static void dp_lookup | ( | int | callno, | |
| const char * | context, | |||
| const char * | callednum, | |||
| const char * | callerid, | |||
| int | skiplock | |||
| ) | [static] |
Definition at line 6057 of file chan_iax2.c.
References ast_canmatch_extension(), ast_exists_extension(), AST_FRAME_IAX, ast_ignore_pattern(), ast_matchmore_extension(), ast_mutex_lock(), ast_mutex_unlock(), ast_parking_ext(), IAX_COMMAND_DPREP, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_NUMBER, IAX_IE_DPSTATUS, IAX_IE_REFRESH, iaxs, iaxsl, and send_command().
Referenced by dp_lookup_thread(), and socket_process().
06058 { 06059 unsigned short dpstatus = 0; 06060 struct iax_ie_data ied1; 06061 int mm; 06062 06063 memset(&ied1, 0, sizeof(ied1)); 06064 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 06065 /* Must be started */ 06066 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 06067 dpstatus = IAX_DPSTATUS_EXISTS; 06068 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 06069 dpstatus = IAX_DPSTATUS_CANEXIST; 06070 } else { 06071 dpstatus = IAX_DPSTATUS_NONEXISTENT; 06072 } 06073 if (ast_ignore_pattern(context, callednum)) 06074 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 06075 if (mm) 06076 dpstatus |= IAX_DPSTATUS_MATCHMORE; 06077 if (!skiplock) 06078 ast_mutex_lock(&iaxsl[callno]); 06079 if (iaxs[callno]) { 06080 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 06081 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 06082 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 06083 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 06084 } 06085 if (!skiplock) 06086 ast_mutex_unlock(&iaxsl[callno]); 06087 }
| static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 6089 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().
06090 { 06091 /* Look up for dpreq */ 06092 struct dpreq_data *dpr = data; 06093 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 06094 if (dpr->callerid) 06095 free(dpr->callerid); 06096 free(dpr); 06097 return NULL; 06098 }
| static int encrypt_frame | ( | aes_encrypt_ctx * | ecx, | |
| struct ast_iax2_full_hdr * | fh, | |||
| unsigned char * | poo, | |||
| int * | datalen | |||
| ) | [static] |
Definition at line 3757 of file chan_iax2.c.
References ast_log(), ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, IAX_FLAG_FULL, memcpy_encrypt(), option_debug, ast_iax2_full_hdr::scallno, and ast_iax2_full_hdr::type.
Referenced by iax2_send().
03758 { 03759 int padding; 03760 unsigned char *workspace; 03761 workspace = alloca(*datalen + 32); 03762 if (!workspace) 03763 return -1; 03764 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 03765 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 03766 if (option_debug && iaxdebug) 03767 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 03768 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 03769 padding = 16 + (padding & 0xf); 03770 memcpy(workspace, poo, padding); 03771 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 03772 workspace[15] &= 0xf0; 03773 workspace[15] |= (padding & 0xf); 03774 if (option_debug && iaxdebug) 03775 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]); 03776 *datalen += padding; 03777 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 03778 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 03779 memcpy(poo, workspace + *datalen - 32, 32); 03780 } else { 03781 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 03782 if (option_debug && iaxdebug) 03783 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen); 03784 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 03785 padding = 16 + (padding & 0xf); 03786 memcpy(workspace, poo, padding); 03787 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 03788 workspace[15] &= 0xf0; 03789 workspace[15] |= (padding & 0x0f); 03790 *datalen += padding; 03791 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 03792 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 03793 memcpy(poo, workspace + *datalen - 32, 32); 03794 } 03795 return 0; 03796 }
| static int expire_registry | ( | void * | data | ) | [static] |
Definition at line 5558 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by iax2_prune_realtime(), reg_source_db(), and update_registry().
05559 { 05560 #ifdef SCHED_MULTITHREADED 05561 if (schedule_action(__expire_registry, data)) 05562 #endif 05563 __expire_registry(data); 05564 return 0; 05565 }
| static struct iax2_dpcache* find_cache | ( | struct ast_channel * | chan, | |
| const char * | data, | |||
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) | [static] |
Definition at line 9423 of file chan_iax2.c.
References ast_calloc, ast_channel_defer_dtmf(), ast_channel_undefer_dtmf(), ast_frfree(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_read(), ast_test_flag, ast_waitfor_nandfds(), CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, cache_get_callno_locked(), iax2_dpcache::callno, dpcache, chan_iax2_pvt::dpentries, iax2_dpcache::expiry, iax2_dpcache::exten, f, iax2_dpcache::flags, free, iax2_dprequest(), IAX_STATE_STARTED, iaxs, iaxsl, LOG_WARNING, iax2_dpcache::next, iax2_dpcache::orig, iax2_dpcache::peer, iax2_dpcache::peercontext, timeout, and iax2_dpcache::waiters.
Referenced by iax2_canmatch(), iax2_exec(), iax2_exists(), and iax2_matchmore().
09424 { 09425 struct iax2_dpcache *dp, *prev = NULL, *next; 09426 struct timeval tv; 09427 int x; 09428 int com[2]; 09429 int timeout; 09430 int old=0; 09431 int outfd; 09432 int abort; 09433 int callno; 09434 struct ast_channel *c; 09435 struct ast_frame *f; 09436 gettimeofday(&tv, NULL); 09437 dp = dpcache; 09438 while(dp) { 09439 next = dp->next; 09440 /* Expire old caches */ 09441 if (ast_tvcmp(tv, dp->expiry) > 0) { 09442 /* It's expired, let it disappear */ 09443 if (prev) 09444 prev->next = dp->next; 09445 else 09446 dpcache = dp->next; 09447 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) { 09448 /* Free memory and go again */ 09449 free(dp); 09450 } else { 09451 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); 09452 } 09453 dp = next; 09454 continue; 09455 } 09456 /* We found an entry that matches us! */ 09457 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 09458 break; 09459 prev = dp; 09460 dp = next; 09461 } 09462 if (!dp) { 09463 /* No matching entry. Create a new one. */ 09464 /* First, can we make a callno? */ 09465 callno = cache_get_callno_locked(data); 09466 if (callno < 0) { 09467 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 09468 return NULL; 09469 } 09470 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 09471 ast_mutex_unlock(&iaxsl[callno]); 09472 return NULL; 09473 } 09474 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 09475 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 09476 gettimeofday(&dp->expiry, NULL); 09477 dp->orig = dp->expiry; 09478 /* Expires in 30 mins by default */ 09479 dp->expiry.tv_sec += iaxdefaultdpcache; 09480 dp->next = dpcache; 09481 dp->flags = CACHE_FLAG_PENDING; 09482 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 09483 dp->waiters[x] = -1; 09484 dpcache = dp; 09485 dp->peer = iaxs[callno]->dpentries; 09486 iaxs[callno]->dpentries = dp; 09487 /* Send the request if we're already up */ 09488 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 09489 iax2_dprequest(dp, callno); 09490 ast_mutex_unlock(&iaxsl[callno]); 09491 } 09492 /* By here we must have a dp */ 09493 if (dp->flags & CACHE_FLAG_PENDING) { 09494 /* Okay, here it starts to get nasty. We need a pipe now to wait 09495 for a reply to come back so long as it's pending */ 09496 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) { 09497 /* Find an empty slot */ 09498 if (dp->waiters[x] < 0) 09499 break; 09500 } 09501 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) { 09502 ast_log(LOG_WARNING, "No more waiter positions available\n"); 09503 return NULL; 09504 } 09505 if (pipe(com)) { 09506 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 09507 return NULL; 09508 } 09509 dp->waiters[x] = com[1]; 09510 /* Okay, now we wait */ 09511 timeout = iaxdefaulttimeout * 1000; 09512 /* Temporarily unlock */ 09513 ast_mutex_unlock(&dpcache_lock); 09514 /* Defer any dtmf */ 09515 if (chan) 09516 old = ast_channel_defer_dtmf(chan); 09517 abort = 0; 09518 while(timeout) { 09519 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 09520 if (outfd > -1) { 09521 break; 09522 } 09523 if (c) { 09524 f = ast_read(c); 09525 if (f) 09526 ast_frfree(f); 09527 else { 09528 /* Got hung up on, abort! */ 09529 break; 09530 abort = 1; 09531 } 09532 } 09533 } 09534 if (!timeout) { 09535 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 09536 } 09537 ast_mutex_lock(&dpcache_lock); 09538 dp->waiters[x] = -1; 09539 close(com[1]); 09540 close(com[0]); 09541 if (abort) { 09542 /* Don't interpret anything, just abort. Not sure what th epoint 09543 of undeferring dtmf on a hung up channel is but hey whatever */ 09544 if (!old && chan) 09545 ast_channel_undefer_dtmf(chan); 09546 return NULL; 09547 } 09548 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 09549 /* Now to do non-independent analysis the results of our wait */ 09550 if (dp->flags & CACHE_FLAG_PENDING) { 09551 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 09552 pending. Don't let it take as long to timeout. */ 09553 dp->flags &= ~CACHE_FLAG_PENDING; 09554 dp->flags |= CACHE_FLAG_TIMEOUT; 09555 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 09556 systems without leaving it unavailable once the server comes back online */ 09557 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 09558 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 09559 if (dp->waiters[x] > -1) 09560 write(dp->waiters[x], "asdf", 4); 09561 } 09562 } 09563 /* Our caller will obtain the rest */ 09564 if (!old && chan) 09565 ast_channel_undefer_dtmf(chan); 09566 } 09567 return dp; 09568 }
| static int find_callno | ( | unsigned short | callno, | |
| unsigned short | dcallno, | |||
| struct sockaddr_in * | sin, | |||
| int | new, | |||
| int | lockpeer, | |||
| int | sockfd | |||
| ) | [static] |
Definition at line 1219 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::amaflags, ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_string_field_set, chan_iax2_pvt::callno, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, globalflags, iax2_getpeername(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, iaxs, iaxsl, chan_iax2_pvt::lagid, LOG_DEBUG, LOG_WARNING, match(), MIN_REUSE_TIME, NEW_ALLOW, new_iax(), option_debug, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingid, chan_iax2_pvt::pingtime, sched, send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, TRUNK_CALL_START, and update_max_nontrunk().
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_poke_peer(), iax2_provision(), iax2_request(), and socket_process().
01220 { 01221 int res = 0; 01222 int x; 01223 struct timeval now; 01224 char host[80]; 01225 if (new <= NEW_ALLOW) { 01226 /* Look for an existing connection first */ 01227 for (x=1;(res < 1) && (x<maxnontrunkcall);x++) { 01228 ast_mutex_lock(&iaxsl[x]); 01229 if (iaxs[x]) { 01230 /* Look for an exact match */ 01231 if (match(sin, callno, dcallno, iaxs[x])) { 01232 res = x; 01233 } 01234 } 01235 ast_mutex_unlock(&iaxsl[x]); 01236 } 01237 for (x=TRUNK_CALL_START;(res < 1) && (x<maxtrunkcall);x++) { 01238 ast_mutex_lock(&iaxsl[x]); 01239 if (iaxs[x]) { 01240 /* Look for an exact match */ 01241 if (match(sin, callno, dcallno, iaxs[x])) { 01242 res = x; 01243 } 01244 } 01245 ast_mutex_unlock(&iaxsl[x]); 01246 } 01247 } 01248 if ((res < 1) && (new >= NEW_ALLOW)) { 01249 /* It may seem odd that we look through the peer list for a name for 01250 * this *incoming* call. Well, it is weird. However, users don't 01251 * have an IP address/port number that we can match against. So, 01252 * this is just checking for a peer that has that IP/port and 01253 * assuming that we have a user of the same name. This isn't always 01254 * correct, but it will be changed if needed after authentication. */ 01255 if (!iax2_getpeername(*sin, host, sizeof(host), lockpeer)) 01256 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 01257 gettimeofday(&now, NULL); 01258 for (x=1;x<TRUNK_CALL_START;x++) { 01259 /* Find first unused call number that hasn't been used in a while */ 01260 ast_mutex_lock(&iaxsl[x]); 01261 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) break; 01262 ast_mutex_unlock(&iaxsl[x]); 01263 } 01264 /* We've still got lock held if we found a spot */ 01265 if (x >= TRUNK_CALL_START) { 01266 ast_log(LOG_WARNING, "No more space\n"); 01267 return 0; 01268 } 01269 iaxs[x] = new_iax(sin, lockpeer, host); 01270 update_max_nontrunk(); 01271 if (iaxs[x]) { 01272 if (option_debug && iaxdebug) 01273 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x); 01274 iaxs[x]->sockfd = sockfd; 01275 iaxs[x]->addr.sin_port = sin->sin_port; 01276 iaxs[x]->addr.sin_family = sin->sin_family; 01277 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 01278 iaxs[x]->peercallno = callno; 01279 iaxs[x]->callno = x; 01280 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 01281 iaxs[x]->expiry = min_reg_expire; 01282 iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01283 iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01284 iaxs[x]->amaflags = amaflags; 01285 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 01286 01287 ast_string_field_set(iaxs[x], accountcode, accountcode); 01288 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 01289 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 01290 } else { 01291 ast_log(LOG_WARNING, "Out of resources\n"); 01292 ast_mutex_unlock(&iaxsl[x]); 01293 return 0; 01294 } 01295 ast_mutex_unlock(&iaxsl[x]); 01296 res = x; 01297 } 01298 return res; 01299 }
| static struct iax2_thread* find_idle_thread | ( | void | ) | [static] |
Definition at line 844 of file chan_iax2.c.
References ast_calloc, ast_cond_init(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_init(), ast_pthread_create, free, iax2_process_thread(), IAX_TYPE_DYNAMIC, iaxdynamicthreadcount, iaxmaxthreadcount, and thread.
Referenced by __schedule_action(), and socket_read().
00845 { 00846 pthread_attr_t attr; 00847 struct iax2_thread *thread = NULL; 00848 00849 /* Pop the head of the list off */ 00850 AST_LIST_LOCK(&idle_list); 00851 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 00852 AST_LIST_UNLOCK(&idle_list); 00853 00854 /* If no idle thread is available from the regular list, try dynamic */ 00855 if (thread == NULL) { 00856 AST_LIST_LOCK(&dynamic_list); 00857 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 00858 /* Make sure we absolutely have a thread... if not, try to make one if allowed */ 00859 if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) { 00860 /* We need to MAKE a thread! */ 00861 if ((thread = ast_calloc(1, sizeof(*thread)))) { 00862 thread->threadnum = iaxdynamicthreadcount; 00863 thread->type = IAX_TYPE_DYNAMIC; 00864 ast_mutex_init(&thread->lock); 00865 ast_cond_init(&thread->cond, NULL); 00866 pthread_attr_init(&attr); 00867 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 00868 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 00869 free(thread); 00870 thread = NULL; 00871 } else { 00872 /* All went well and the thread is up, so increment our count */ 00873 iaxdynamicthreadcount++; 00874 } 00875 } 00876 } 00877 AST_LIST_UNLOCK(&dynamic_list); 00878 } 00879 00880 return thread; 00881 }
| static struct iax2_peer* find_peer | ( | const char * | name, | |
| int | realtime | |||
| ) | [static] |
Definition at line 1003 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and realtime_peer().
01004 { 01005 struct iax2_peer *peer = NULL; 01006 01007 /* Grab peer from linked list */ 01008 AST_LIST_LOCK(&peers); 01009 AST_LIST_TRAVERSE(&peers, peer, entry) { 01010 if (!strcasecmp(peer->name, name)) { 01011 break; 01012 } 01013 } 01014 AST_LIST_UNLOCK(&peers); 01015 01016 /* Now go for realtime if applicable */ 01017 if(!peer && realtime) 01018 peer = realtime_peer(name, NULL); 01019 return peer; 01020 }
| static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
| int | fd | |||
| ) | [static] |
Definition at line 3568 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_mutex_lock(), inaddrcmp(), iax2_trunk_peer::lock, iax2_trunk_peer::next, and tpeers.
Referenced by iax2_trunk_queue(), and socket_process().
03569 { 03570 struct iax2_trunk_peer *tpeer; 03571 03572 /* Finds and locks trunk peer */ 03573 ast_mutex_lock(&tpeerlock); 03574 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) { 03575 /* We don't lock here because tpeer->addr *never* changes */ 03576 if (!inaddrcmp(&tpeer->addr, sin)) { 03577 ast_mutex_lock(&tpeer->lock); 03578 break; 03579 } 03580 } 03581 if (!tpeer) { 03582 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 03583 ast_mutex_init(&tpeer->lock); 03584 tpeer->lastsent = 9999; 03585 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 03586 tpeer->trunkact = ast_tvnow(); 03587 ast_mutex_lock(&tpeer->lock); 03588 tpeer->next = tpeers; 03589 tpeer->sockfd = fd; 03590 tpeers = tpeer; 03591 #ifdef SO_NO_CHECK 03592 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 03593 #endif 03594 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 03595 } 03596 } 03597 ast_mutex_unlock(&tpeerlock); 03598 return tpeer; 03599 }
| static unsigned int fix_peerts | ( | struct timeval * | tv, | |
| int | callno, | |||
| unsigned int | ts | |||
| ) | [static] |
Definition at line 3395 of file chan_iax2.c.
References iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process().
03396 { 03397 long ms; /* NOT unsigned */ 03398 if (ast_tvzero(iaxs[callno]->rxcore)) { 03399 /* Initialize rxcore time if appropriate */ 03400 gettimeofday(&iaxs[callno]->rxcore, NULL); 03401 /* Round to nearest 20ms so traces look pretty */ 03402 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 03403 } 03404 /* Calculate difference between trunk and channel */ 03405 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore); 03406 /* Return as the sum of trunk time and the difference between trunk and real time */ 03407 return ms + ts; 03408 }
| static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 8031 of file chan_iax2.c.
References free, and iax2_context::next.
Referenced by build_user(), and destroy_user().
08032 { 08033 struct iax2_context *conl; 08034 while(con) { 08035 conl = con; 08036 con = con->next; 08037 free(conl); 08038 } 08039 }
| static int function_iaxpeer | ( | struct ast_channel * | chan, | |
| char * | cmd, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 9692 of file chan_iax2.c.
References iax2_peer::addr, ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strdupa, ast_test_flag, iax2_peer::capability, iax2_peer::expire, find_peer(), iax2_tech, IAX_DYNAMIC, iaxs, peer_status(), iax2_peer::prefs, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.
09693 { 09694 struct iax2_peer *peer; 09695 char *peername, *colname; 09696 09697 peername = ast_strdupa(data); 09698 09699 /* if our channel, return the IP address of the endpoint of current channel */ 09700 if (!strcmp(peername,"CURRENTCHANNEL")) { 09701 unsigned short callno; 09702 if (chan->tech != &iax2_tech) 09703 return -1; 09704 callno = PTR_TO_CALLNO(chan->tech_pvt); 09705 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 09706 return 0; 09707 } 09708 09709 if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */ 09710 *colname++ = '\0'; 09711 else if ((colname = strchr(peername, '|'))) 09712 *colname++ = '\0'; 09713 else 09714 colname = "ip"; 09715 09716 if (!(peer = find_peer(peername, 1))) 09717 return -1; 09718 09719 if (!strcasecmp(colname, "ip")) { 09720 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 09721 } else if (!strcasecmp(colname, "status")) { 09722 peer_status(peer, buf, len); 09723 } else if (!strcasecmp(colname, "mailbox")) { 09724 ast_copy_string(buf, peer->mailbox, len); 09725 } else if (!strcasecmp(colname, "context")) { 09726 ast_copy_string(buf, peer->context, len); 09727 } else if (!strcasecmp(colname, "expire")) { 09728 snprintf(buf, len, "%d", peer->expire); 09729 } else if (!strcasecmp(colname, "dynamic")) { 09730 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 09731 } else if (!strcasecmp(colname, "callerid_name")) { 09732 ast_copy_string(buf, peer->cid_name, len); 09733 } else if (!strcasecmp(colname, "callerid_num")) { 09734 ast_copy_string(buf, peer->cid_num, len); 09735 } else if (!strcasecmp(colname, "codecs")) { 09736 ast_getformatname_multiple(buf, len -1, peer->capability); 09737 } else if (!strncasecmp(colname, "codec[", 6)) { 09738 char *codecnum, *ptr; 09739 int index = 0, codec = 0; 09740 09741 codecnum = strchr(colname, '['); 09742 *codecnum = '\0'; 09743 codecnum++; 09744 if ((ptr = strchr(codecnum, ']'))) { 09745 *ptr = '\0'; 09746 } 09747 index = atoi(codecnum); 09748 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 09749 ast_copy_string(buf, ast_getformatname(codec), len); 09750 } 09751 } 09752 09753 return 0; 09754 }
| static int get_auth_methods | ( | char * | value | ) | [static] |
Definition at line 8257 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
08258 { 08259 int methods = 0; 08260 if (strstr(value, "rsa")) 08261 methods |= IAX_AUTH_RSA; 08262 if (strstr(value, "md5")) 08263 methods |= IAX_AUTH_MD5; 08264 if (strstr(value, "plaintext")) 08265 methods |= IAX_AUTH_PLAINTEXT; 08266 return methods; 08267 }
| static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 934 of file chan_iax2.c.
References ast_true(), and IAX_ENCRYPT_AES128.
Referenced by build_peer(), build_user(), and set_config().
00935 { 00936 int e; 00937 if (!strcasecmp(s, "aes128")) 00938 e = IAX_ENCRYPT_AES128; 00939 else if (ast_true(s)) 00940 e = IAX_ENCRYPT_AES128; 00941 else 00942 e = 0; 00943 return e; 00944 }
| static int get_from_jb | ( | void * | p | ) | [static] |
Definition at line 2309 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
02310 { 02311 #ifdef SCHED_MULTITHREADED 02312 if (schedule_action(__get_from_jb, data)) 02313 #endif 02314 __get_from_jb(data); 02315 return 0; 02316 }
| static int handle_error | ( | void | ) | [static] |
Definition at line 1606 of file chan_iax2.c.
References ast_inet_ntoa(), ast_log(), LOG_WARNING, and netsocket.
Referenced by send_packet(), socket_read(), and transmit_trunk().
01607 { 01608 /* XXX Ideally we should figure out why an error occured and then abort those 01609 rather than continuing to try. Unfortunately, the published interface does 01610 not seem to work XXX */ 01611 #if 0 01612 struct sockaddr_in *sin; 01613 int res; 01614 struct msghdr m; 01615 struct sock_extended_err e; 01616 m.msg_name = NULL; 01617 m.msg_namelen = 0; 01618 m.msg_iov = NULL; 01619 m.msg_control = &e; 01620 m.msg_controllen = sizeof(e); 01621 m.msg_flags = 0; 01622 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 01623 if (res < 0) 01624 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 01625 else { 01626 if (m.msg_controllen) { 01627 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 01628 if (sin) 01629 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 01630 else 01631 ast_log(LOG_WARNING, "No address detected??\n"); 01632 } else { 01633 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 01634 } 01635 } 01636 #endif 01637 return 0; 01638 }
| static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
| struct sockaddr_in * | sin, | |||
| int | callno | |||
| ) | [static] |
Acknowledgment received for OUR registration.
Definition at line 5387 of file chan_iax2.c.
References iax2_registry::addr, ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_verbose(), EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), iaxs, ies, inaddrcmp(), LOG_WARNING, manager_event(), iax2_registry::messages, option_verbose, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGISTERED, iax2_registry::regstate, sched, iax2_registry::us, and VERBOSE_PREFIX_3.
Referenced by socket_process().
05388 { 05389 struct iax2_registry *reg; 05390 /* Start pessimistic */ 05391 char peer[256] = ""; 05392 char msgstatus[60]; 05393 int refresh = 60; 05394 char ourip[256] = "<Unspecified>"; 05395 struct sockaddr_in oldus; 05396 struct sockaddr_in us; 05397 int oldmsgs; 05398 05399 memset(&us, 0, sizeof(us)); 05400 if (ies->apparent_addr) 05401 bcopy(ies->apparent_addr, &us, sizeof(us)); 05402 if (ies->username) 05403 ast_copy_string(peer, ies->username, sizeof(peer)); 05404 if (ies->refresh) 05405 refresh = ies->refresh; 05406 if (ies->calling_number) { 05407 /* We don't do anything with it really, but maybe we should */ 05408 } 05409 reg = iaxs[callno]->reg; 05410 if (!reg) { 05411 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 05412 return -1; 05413 } 05414 memcpy(&oldus, ®->us, sizeof(oldus)); 05415 oldmsgs = reg->messages; 05416 if (inaddrcmp(®->addr, sin)) { 05417 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 05418 return -1; 05419 } 05420 memcpy(®->us, &us, sizeof(reg->us)); 05421 if (ies->msgcount >= 0) 05422 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 05423 /* always refresh the registration at the interval requested by the server 05424 we are registering to 05425 */ 05426 reg->refresh = refresh; 05427 if (reg->expire > -1) 05428 ast_sched_del(sched, reg->expire); 05429 reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 05430 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 05431 if (option_verbose > 2) { 05432 if (reg->messages > 255) 05433 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 05434 else if (reg->messages > 1) 05435 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages); 05436 else if (reg->messages > 0) 05437 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n"); 05438 else 05439 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n"); 05440 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 05441 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 05442 } 05443 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 05444 } 05445 reg->regstate = REG_STATE_REGISTERED; 05446 return 0; 05447 }
| static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3218 of file chan_iax2.c.
References AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_log(), option_debug, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03219 { 03220 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03221 if (option_debug) 03222 ast_log(LOG_DEBUG, "Answering IAX2 call\n"); 03223 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 03224 }
| 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 3074 of file chan_iax2.c.
References AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED_NOWARN, ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), chan_iax2_pvt::bridgecallno, f, iax2_tech, iaxs, iaxsl, lock_both(), option_verbose, PTR_TO_CALLNO, ast_channel::tech, ast_channel::tech_pvt, tv, unlock_both(), and VERBOSE_PREFIX_3.
03075 { 03076 struct ast_channel *cs[3]; 03077 struct ast_channel *who, *other; 03078 int to = -1; 03079 int res = -1; 03080 int transferstarted=0; 03081 struct ast_frame *f; 03082 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 03083 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 03084 struct timeval waittimer = {0, 0}, tv; 03085 03086 lock_both(callno0, callno1); 03087 /* Put them in native bridge mode */ 03088 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) { 03089 iaxs[callno0]->bridgecallno = callno1; 03090 iaxs[callno1]->bridgecallno = callno0; 03091 } 03092 unlock_both(callno0, callno1); 03093 03094 /* If not, try to bridge until we can execute a transfer, if we can */ 03095 cs[0] = c0; 03096 cs[1] = c1; 03097 for (/* ever */;;) { 03098 /* Check in case we got masqueraded into */ 03099 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 03100 if (option_verbose > 2) 03101 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n"); 03102 /* Remove from native mode */ 03103 if (c0->tech == &iax2_tech) { 03104 ast_mutex_lock(&iaxsl[callno0]); 03105 iaxs[callno0]->bridgecallno = 0; 03106 ast_mutex_unlock(&iaxsl[callno0]); 03107 } 03108 if (c1->tech == &iax2_tech) { 03109 ast_mutex_lock(&iaxsl[callno1]); 03110 iaxs[callno1]->bridgecallno = 0; 03111 ast_mutex_unlock(&iaxsl[callno1]); 03112 } 03113 return AST_BRIDGE_FAILED_NOWARN; 03114 } 03115 if (c0->nativeformats != c1->nativeformats) { 03116 if (option_verbose > 2) { 03117 char buf0[255]; 03118 char buf1[255]; 03119 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 03120 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 03121 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 03122 } 03123 /* Remove from native mode */ 03124 lock_both(callno0, callno1); 03125 iaxs[callno0]->bridgecallno = 0; 03126 iaxs[callno1]->bridgecallno = 0; 03127 unlock_both(callno0, callno1); 03128 return AST_BRIDGE_FAILED_NOWARN; 03129 } 03130 /* check if transfered and if we really want native bridging */ 03131 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) { 03132 /* Try the transfer */ 03133 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 03134 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA))) 03135 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 03136 transferstarted = 1; 03137 } 03138 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 03139 /* Call has been transferred. We're no longer involved */ 03140 gettimeofday(&tv, NULL); 03141 if (ast_tvzero(waittimer)) { 03142 waittimer = tv; 03143 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 03144 c0->_softhangup |= AST_SOFTHANGUP_DEV; 03145 c1->_softhangup |= AST_SOFTHANGUP_DEV; 03146 *fo = NULL; 03147 *rc = c0; 03148 res = AST_BRIDGE_COMPLETE; 03149 break; 03150 } 03151 } 03152 to = 1000; 03153 who = ast_waitfor_n(cs, 2, &to); 03154 if (timeoutms > -1) { 03155 timeoutms -= (1000 - to); 03156 if (timeoutms < 0) 03157 timeoutms = 0; 03158 } 03159 if (!who) { 03160 if (!timeoutms) { 03161 res = AST_BRIDGE_RETRY; 03162 break; 03163 } 03164 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 03165 res = AST_BRIDGE_FAILED; 03166 break; 03167 } 03168 continue; 03169 } 03170 f = ast_read(who); 03171 if (!f) { 03172 *fo = NULL; 03173 *rc = who; 03174 res = AST_BRIDGE_COMPLETE; 03175 break; 03176 } 03177 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 03178 *fo = f; 03179 *rc = who; 03180 res = AST_BRIDGE_COMPLETE; 03181 break; 03182 } 03183 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 03184 if ((f->frametype == AST_FRAME_VOICE) || 03185 (f->frametype == AST_FRAME_TEXT) || 03186 (f->frametype == AST_FRAME_VIDEO) || 03187 (f->frametype == AST_FRAME_IMAGE) || 03188 (f->frametype == AST_FRAME_DTMF)) { 03189 /* monitored dtmf take out of the bridge. 03190 * check if we monitor the specific source. 03191 */ 03192 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 03193 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 03194 *rc = who; 03195 *fo = f; 03196 res = AST_BRIDGE_COMPLETE; 03197 /* Remove from native mode */ 03198 break; 03199 } 03200 /* everything else goes to the other side */ 03201 ast_write(other, f); 03202 } 03203 ast_frfree(f); 03204 /* Swap who gets priority */ 03205 cs[2] = cs[0]; 03206 cs[0] = cs[1]; 03207 cs[1] = cs[2]; 03208 } 03209 lock_both(callno0, callno1); 03210 if(iaxs[callno0]) 03211 iaxs[callno0]->bridgecallno = 0; 03212 if(iaxs[callno1]) 03213 iaxs[callno1]->bridgecallno = 0; 03214 unlock_both(callno0, callno1); 03215 return res; 03216 }
| static int iax2_call | ( | struct ast_channel * | c, | |
| char * | dest, | |||
| int | timeout | |||
| ) | [static] |
Definition at line 2820 of file chan_iax2.c.
References ast_channel::_state, chan_iax2_pvt::adsi, ast_channel::adsicpe, AST_FRAME_IAX, AST_LIST_TRAVERSE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PRES_NUMBER_NOT_AVAILABLE, ast_sched_add(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_var_name(), ast_var_value(), auto_congest(), CALLNO_TO_PTR, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, create_addr(), chan_iax2_pvt::encmethods, iax2_datetime(), IAX_COMMAND_NEW, IAX_IE_ADSICPE, iax_ie_append(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTOANSWER, IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CALLING_ANI, IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_CALLINGPRES, IAX_IE_CALLINGTNS, IAX_IE_CALLINGTON, IAX_IE_CAPABILITY, IAX_IE_CODEC_PREFS, IAX_IE_DATETIME, IAX_IE_DNID, IAX_IE_ENCRYPTION, IAX_IE_FORMAT, IAX_IE_LANGUAGE, IAX_IE_RDNIS, IAX_IE_USERNAME, IAX_IE_VARIABLE, IAX_IE_VERSION, IAX_PROTO_VERSION, IAX_SENDANI, iaxs, iaxsl, chan_iax2_pvt::initid, LOG_WARNING, chan_iax2_pvt::maxtime, ast_channel::nativeformats, parse_dial_string(), chan_iax2_pvt::pingtime, PTR_TO_CALLNO, sched, send_command(), chan_iax2_pvt::sockfd, ast_channel::tech_pvt, var, and ast_channel::varshead.
02821 { 02822 struct sockaddr_in sin; 02823 char *l=NULL, *n=NULL, *tmpstr; 02824 struct iax_ie_data ied; 02825 char *defaultrdest = "s"; 02826 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 02827 struct parsed_dial_string pds; 02828 struct create_addr_info cai; 02829 struct ast_var_t *var; 02830 02831 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 02832 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 02833 return -1; 02834 } 02835 02836 memset(&cai, 0, sizeof(cai)); 02837 cai.encmethods = iax2_encryption; 02838 02839 memset(&pds, 0, sizeof(pds)); 02840 tmpstr = ast_strdupa(dest); 02841 parse_dial_string(tmpstr, &pds); 02842 02843 if (!pds.exten) 02844 pds.exten = defaultrdest; 02845 02846 if (create_addr(pds.peer, &sin, &cai)) { 02847 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 02848 return -1; 02849 } 02850 02851 if (!pds.username && !ast_strlen_zero(cai.username)) 02852 pds.username = cai.username; 02853 if (!pds.password && !ast_strlen_zero(cai.secret)) 02854 pds.password = cai.secret; 02855 if (!pds.key && !ast_strlen_zero(cai.outkey)) 02856 pds.key = cai.outkey; 02857 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 02858 pds.context = cai.peercontext; 02859 02860 /* Keep track of the context for outgoing calls too */ 02861 ast_copy_string(c->context, cai.context, sizeof(c->context)); 02862 02863 if (pds.port) 02864 sin.sin_port = htons(atoi(pds.port)); 02865 02866 l = c->cid.cid_num; 02867 n = c->cid.cid_name; 02868 02869 /* Now build request */ 02870 memset(&ied, 0, sizeof(ied)); 02871 02872 /* On new call, first IE MUST be IAX version of caller */ 02873 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 02874 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 02875 if (pds.options && strchr(pds.options, 'a')) { 02876 /* Request auto answer */ 02877 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 02878 } 02879 02880 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 02881 02882 if (l) { 02883 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 02884 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 02885 } else { 02886 if (n) 02887 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 02888 else 02889 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 02890 } 02891 02892 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton); 02893 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns); 02894 02895 if (n) 02896 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 02897 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani) 02898 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani); 02899 02900 if (!ast_strlen_zero(c->language)) 02901 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 02902 if (!ast_strlen_zero(c->cid.cid_dnid)) 02903 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid); 02904 if (!ast_strlen_zero(c->cid.cid_rdnis)) 02905 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis); 02906 02907 if (pds.context) 02908 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 02909 02910 if (pds.username) 02911 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 02912 02913 if (cai.encmethods) 02914 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 02915 02916 ast_mutex_lock(&iaxsl[callno]); 02917 02918 if (!ast_strlen_zero(c->context)) 02919 ast_string_field_set(iaxs[callno], context, c->context); 02920 02921 if (pds.username) 02922 ast_string_field_set(iaxs[callno], username, pds.username); 02923 02924 iaxs[callno]->encmethods = cai.encmethods; 02925 02926 iaxs[callno]->adsi = cai.adsi; 02927 02928 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 02929 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 02930 02931 if (pds.key) 02932 ast_string_field_set(iaxs[callno], outkey, pds.key); 02933 if (pds.password) 02934 ast_string_field_set(iaxs[callno], secret, pds.password); 02935 02936 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); 02937 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); 02938 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 02939 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 02940 02941 if (iaxs[callno]->maxtime) { 02942 /* Initialize pingtime and auto-congest time */ 02943 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 02944 iaxs[callno]->initid = ast_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 02945 } else if (autokill) { 02946 iaxs[callno]->pingtime = autokill / 2; 02947 iaxs[callno]->initid = ast_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 02948 } 02949 02950 /* Add remote vars */ 02951 AST_LIST_TRAVERSE(&c->varshead, var, entries) { 02952 if (!strncmp(ast_var_name(var), "~IAX2~", strlen("~IAX2~"))) { 02953 char tmp[256]; 02954 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var) + strlen("~IAX2~"), ast_var_value(var)); 02955 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp); 02956 } 02957 } 02958 02959 /* send the command using the appropriate socket for this peer */ 02960 iaxs[callno]->sockfd = cai.sockfd; 02961 02962 /* Transmit the string in a "NEW" request */ 02963 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 02964 02965 ast_mutex_unlock(&iaxsl[callno]); 02966 ast_setstate(c, AST_STATE_RINGING); 02967 02968 return 0; 02969 }
| 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 9594 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.
09595 { 09596 int res = 0; 09597 struct iax2_dpcache *dp; 09598 #if 0 09599 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 09600 #endif 09601 if ((priority != 1) && (priority != 2)) 09602 return 0; 09603 ast_mutex_lock(&dpcache_lock); 09604 dp = find_cache(chan, data, context, exten, priority); 09605 if (dp) { 09606 if (dp->flags & CACHE_FLAG_CANEXIST) 09607 res= 1; 09608 } 09609 ast_mutex_unlock(&dpcache_lock); 09610 if (!dp) { 09611 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 09612 } 09613 return res; 09614 }
| static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 2733 of file chan_iax2.c.
References ast_localtime(), ast_strlen_zero(), and t.
Referenced by iax2_call(), and update_registry().
02734 { 02735 time_t t; 02736 struct tm tm; 02737 unsigned int tmp; 02738 time(&t); 02739 localtime_r(&t, &tm); 02740 if (!ast_strlen_zero(tz)) 02741 ast_localtime(&t, &tm, tz); 02742 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 02743 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 02744 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 02745 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 02746 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 02747 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 02748 return tmp; 02749 }
| static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 1753 of file chan_iax2.c.
References ast_channel::_softhangup, 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_SOFTHANGUP_DEV, ast_string_field_free_pools, ast_variables_destroy(), iax2_registry::callno, chan_iax2_pvt::callno, iax_frame::callno, jb_frame::data, free, iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, iaxq, iaxs, iaxsl, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, 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(), destroy_peer(), iax2_do_register(), iax2_hangup(), iax2_poke_peer(), and socket_process().
01754 { 01755 struct chan_iax2_pvt *pvt; 01756 struct iax_frame *cur; 01757 struct ast_channel *owner; 01758 01759 retry: 01760 pvt = iaxs[callno]; 01761 gettimeofday(&lastused[callno], NULL); 01762 01763 owner = pvt ? pvt->owner : NULL; 01764 01765 if (owner) { 01766 if (ast_mutex_trylock(&owner->lock)) { 01767 ast_log(LOG_NOTICE, "Avoiding IAX destroy deadlock\n"); 01768 ast_mutex_unlock(&iaxsl[callno]); 01769 usleep(1); 01770 ast_mutex_lock(&iaxsl[callno]); 01771 goto retry; 01772 } 01773 } 01774 if (!owner) 01775 iaxs[callno] = NULL; 01776 if (pvt) { 01777 if (!owner) 01778 pvt->owner = NULL; 01779 iax2_destroy_helper(pvt); 01780 01781 /* Already gone */ 01782 ast_set_flag(pvt, IAX_ALREADYGONE); 01783 01784 if (owner) { 01785 /* If there's an owner, prod it to give up */ 01786 owner->_softhangup |= AST_SOFTHANGUP_DEV; 01787 ast_queue_hangup(owner); 01788 } 01789 01790 AST_LIST_LOCK(&iaxq.queue); 01791 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 01792 /* Cancel any pending transmissions */ 01793 if (cur->callno == pvt->callno) 01794 cur->retries = -1; 01795 } 01796 AST_LIST_UNLOCK(&iaxq.queue); 01797 01798 if (pvt->reg) 01799 pvt->reg->callno = 0; 01800 if (!owner) { 01801 jb_frame frame; 01802 if (pvt->vars) { 01803 ast_variables_destroy(pvt->vars); 01804 pvt->vars = NULL; 01805 } 01806 01807 while (jb_getall(pvt->jb, &frame) == JB_OK) 01808 iax2_frame_free(frame.data); 01809 jb_destroy(pvt->jb); 01810 /* gotta free up the stringfields */ 01811 ast_string_field_free_pools(pvt); 01812 free(pvt); 01813 } 01814 } 01815 if (owner) { 01816 ast_mutex_unlock(&owner->lock); 01817 } 01818 if (callno & 0x4000) 01819 update_max_trunk(); 01820 }
| static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1694 of file chan_iax2.c.
References ast_clear_flag, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, 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, and sched.
Referenced by iax2_destroy(), iax2_predestroy(), and stop_stuff().
01695 { 01696 struct iax2_user *user = NULL; 01697 01698 /* Decrement AUTHREQ count if needed */ 01699 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01700 AST_LIST_LOCK(&users); 01701 AST_LIST_TRAVERSE(&users, user, entry) { 01702 if (!strcmp(user->name, pvt->username)) { 01703 user->curauthreq--; 01704 break; 01705 } 01706 } 01707 AST_LIST_UNLOCK(&users); 01708 ast_clear_flag(pvt, IAX_MAXAUTHREQ); 01709 } 01710 /* No more pings or lagrq's */ 01711 if (pvt->pingid > -1) 01712 ast_sched_del(sched, pvt->pingid); 01713 pvt->pingid = -1; 01714 if (pvt->lagid > -1) 01715 ast_sched_del(sched, pvt->lagid); 01716 pvt->lagid = -1; 01717 if (pvt->autoid > -1) 01718 ast_sched_del(sched, pvt->autoid); 01719 pvt->autoid = -1; 01720 if (pvt->authid > -1) 01721 ast_sched_del(sched, pvt->authid); 01722 pvt->authid = -1; 01723 if (pvt->initid > -1) 01724 ast_sched_del(sched, pvt->initid); 01725 pvt->initid = -1; 01726 if (pvt->jbid > -1) 01727 ast_sched_del(sched, pvt->jbid); 01728 pvt->jbid = -1; 01729 }
| static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 9779 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(), ast_test_flag, iax2_peer::defaddr, destroy_peer(), find_peer(), iax2_peer::historicms, IAX_TEMPONLY, iax2_peer::lastms, iax2_peer::maxms, option_debug, and parse_dial_string().
09780 { 09781 struct parsed_dial_string pds; 09782 char *tmp = ast_strdupa(data); 09783 struct iax2_peer *p; 09784 int res = AST_DEVICE_INVALID; 09785 09786 memset(&pds, 0, sizeof(pds)); 09787 parse_dial_string(tmp, &pds); 09788 if (ast_strlen_zero(pds.peer)) 09789 return res; 09790 09791 if (option_debug > 2) 09792 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer); 09793 09794 /* SLD: FIXME: second call to find_peer during registration */ 09795 if (!(p = find_peer(pds.peer, 1))) 09796 return res; 09797 09798 res = AST_DEVICE_UNAVAILABLE; 09799 if (option_debug > 2) 09800 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 09801 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 09802 09803 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 09804 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 09805 /* Peer is registered, or have default IP address 09806 and a valid registration */ 09807 if (p->historicms == 0 || p->historicms <= p->maxms) 09808 /* let the core figure out whether it is in use or not */ 09809 res = AST_DEVICE_UNKNOWN; 09810 } 09811 09812 if (ast_test_flag(p, IAX_TEMPONLY)) 09813 destroy_peer(p); 09814 09815 return res; 09816 }
| static int iax2_digit_begin | ( | struct ast_channel * | c, | |
| char | digit | |||
| ) | [static] |
Definition at line 2417 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02418 { 02419 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 02420 }
| static int iax2_digit_end | ( | struct ast_channel * | c, | |
| char | digit, | |||
| unsigned int | duration | |||
| ) | [static] |
Definition at line 2422 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02423 { 02424 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 02425 }
| static int iax2_do_debug | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 4474 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04475 { 04476 if (argc < 2 || argc > 3) 04477 return RESULT_SHOWUSAGE; 04478 iaxdebug = 1; 04479 ast_cli(fd, "IAX2 Debugging Enabled\n"); 04480 return RESULT_SUCCESS; 04481 }
| static int iax2_do_jb_debug | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 4492 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04493 { 04494 if (argc < 3 || argc > 4) 04495 return RESULT_SHOWUSAGE; 04496 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 04497 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 04498 return RESULT_SUCCESS; 04499 }
| static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 7776 of file chan_iax2.c.
References iax2_registry::addr, ast_dnsmgr_changed(), ast_dnsmgr_refresh(), AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, find_callno(), iax2_destroy(), iax2_do_register_s(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, iaxsl, LOG_WARNING, NEW_FORCE, option_debug, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), and iax2_registry::username.
Referenced by __iax2_do_register_s(), load_module(), and reload_config().
07777 { 07778 struct iax_ie_data ied; 07779 if (option_debug && iaxdebug) 07780 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username); 07781 07782 if (reg->dnsmgr && 07783 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) { 07784 /* Maybe the IP has changed, force DNS refresh */ 07785 ast_dnsmgr_refresh(reg->dnsmgr); 07786 } 07787 07788 /* 07789 * if IP has Changed, free allocated call to create a new one with new IP 07790 * call has the pointer to IP and must be updated to the new one 07791 */ 07792 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 07793 ast_mutex_lock(&iaxsl[reg->callno]); 07794 iax2_destroy(reg->callno); 07795 ast_mutex_unlock(&iaxsl[reg->callno]); 07796 reg->callno = 0; 07797 } 07798 if (!reg->addr.sin_addr.s_addr) { 07799 if (option_debug && iaxdebug) 07800 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username); 07801 /* Setup the next registration attempt */ 07802 if (reg->expire > -1) 07803 ast_sched_del(sched, reg->expire); 07804 reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 07805 return -1; 07806 } 07807 07808 if (!reg->callno) { 07809 if (option_debug) 07810 ast_log(LOG_DEBUG, "Allocate call number\n"); 07811 reg->callno = find_callno(0, 0, ®->addr, NEW_FORCE, 1, defaultsockfd); 07812 if (reg->callno < 1) { 07813 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 07814 return -1; 07815 } else if (option_debug) 07816 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno); 07817 iaxs[reg->callno]->reg = reg; 07818 } 07819 /* Schedule the next registration attempt */ 07820 if (reg->expire > -1) 07821 ast_sched_del(sched, reg->expire); 07822 /* Setup the next registration a little early */ 07823 reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 07824 /* Send the request */ 07825 memset(&ied, 0, sizeof(ied)); 07826 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 07827 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 07828 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 07829 reg->regstate = REG_STATE_REGSENT; 07830 return 0; 07831 }
| static int iax2_do_register_s | ( | void * | data | ) | [static] |
Definition at line 5241 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
05242 { 05243 #ifdef SCHED_MULTITHREADED 05244 if (schedule_action(__iax2_do_register_s, data)) 05245 #endif 05246 __iax2_do_register_s(data); 05247 return 0; 05248 }
| static int iax2_do_trunk_debug | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 4483 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04484 { 04485 if (argc < 3 || argc > 4) 04486 return RESULT_SHOWUSAGE; 04487 iaxtrunkdebug = 1; 04488 ast_cli(fd, "IAX2 Trunk Debug Requested\n"); 04489 return RESULT_SUCCESS; 04490 }
| static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
| int | callno | |||
| ) | [static] |
Definition at line 5874 of file chan_iax2.c.
References AST_FRAME_IAX, ast_sched_add(), ast_sched_del(), auto_hangup(), chan_iax2_pvt::autoid, CACHE_FLAG_TRANSMITTED, iax2_dpcache::exten, iax2_dpcache::flags, IAX_COMMAND_DPREQ, iax_ie_append_str(), IAX_IE_CALLED_NUMBER, iaxs, sched, and send_command().
Referenced by find_cache(), and socket_process().
05875 { 05876 struct iax_ie_data ied; 05877 /* Auto-hangup with 30 seconds of inactivity */ 05878 if (iaxs[callno]->autoid > -1) 05879 ast_sched_del(sched, iaxs[callno]->autoid); 05880 iaxs[callno]->autoid = ast_sched_add(sched, 30000, auto_hangup, (void *)(long)callno); 05881 memset(&ied, 0, sizeof(ied)); 05882 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 05883 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 05884 dp->flags |= CACHE_FLAG_TRANSMITTED; 05885 }
| 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 9640 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.
09641 { 09642 char odata[256]; 09643 char req[256]; 09644 char *ncontext; 09645 struct iax2_dpcache *dp; 09646 struct ast_app *dial; 09647 #if 0 09648 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); 09649 #endif 09650 if (priority == 2) { 09651 /* Indicate status, can be overridden in dialplan */ 09652 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 09653 if (dialstatus) { 09654 dial = pbx_findapp(dialstatus); 09655 if (dial) 09656 pbx_exec(chan, dial, ""); 09657 } 09658 return -1; 09659 } else if (priority != 1) 09660 return -1; 09661 ast_mutex_lock(&dpcache_lock); 09662 dp = find_cache(chan, data, context, exten, priority); 09663 if (dp) { 09664 if (dp->flags & CACHE_FLAG_EXISTS) { 09665 ast_copy_string(odata, data, sizeof(odata)); 09666 ncontext = strchr(odata, '/'); 09667 if (ncontext) { 09668 *ncontext = '\0'; 09669 ncontext++; 09670 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 09671 } else { 09672 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 09673 } 09674 if (option_verbose > 2) 09675 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req); 09676 } else { 09677 ast_mutex_unlock(&dpcache_lock); 09678 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 09679 return -1; 09680 } 09681 } 09682 ast_mutex_unlock(&dpcache_lock); 09683 dial = pbx_findapp("Dial"); 09684 if (dial) { 09685 return pbx_exec(chan, dial, req); 09686 } else { 09687 ast_log(LOG_WARNING, "No dial application registered\n"); 09688 } 09689 return -1; 09690 }
| 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 9571 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.
09572 { 09573 struct iax2_dpcache *dp; 09574 int res = 0; 09575 #if 0 09576 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 09577 #endif 09578 if ((priority != 1) && (priority != 2)) 09579 return 0; 09580 ast_mutex_lock(&dpcache_lock); 09581 dp = find_cache(chan, data, context, exten, priority); 09582 if (dp) { 09583 if (dp->flags & CACHE_FLAG_EXISTS) 09584 res= 1; 09585 } 09586 ast_mutex_unlock(&dpcache_lock); 09587 if (!dp) { 09588 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 09589 } 09590 return res; 09591 }
| static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
| struct ast_channel * | newchan | |||
| ) | [static] |
Definition at line 2444 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iaxs, iaxsl, LOG_WARNING, chan_iax2_pvt::owner, PTR_TO_CALLNO, and ast_channel::tech_pvt.
02445 { 02446 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 02447 ast_mutex_lock(&iaxsl[callno]); 02448 if (iaxs[callno]) 02449 iaxs[callno]->owner = newchan; 02450 else 02451 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 02452 ast_mutex_unlock(&iaxsl[callno]); 02453 return 0; 02454 }
| static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1301 of file chan_iax2.c.
References ast_sched_del(), iax_frame_free(), iax_frame::retrans, and sched.
Referenced by __attempt_transmit(), __do_deliver(), __get_from_jb(), complete_transfer(), iax2_destroy(), and schedule_delivery().
01302 { 01303 if (fr->retrans > -1) 01304 ast_sched_del(sched, fr->retrans); 01305 iax_frame_free(fr); 01306 }
| static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
| char * | host, | |||
| int | len, | |||
| int | lockpeer | |||
| ) | [static] |
Definition at line 1022 of file chan_iax2.c.
References iax2_peer::addr, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_test_flag, destroy_peer(), IAX_TEMPONLY, and realtime_peer().
Referenced by find_callno().
01023 { 01024 struct iax2_peer *peer = NULL; 01025 int res = 0; 01026 01027 if (lockpeer) 01028 AST_LIST_LOCK(&peers); 01029 AST_LIST_TRAVERSE(&peers, peer, entry) { 01030 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01031 (peer->addr.sin_port == sin.sin_port)) { 01032 ast_copy_string(host, peer->name, len); 01033 res = 1; 01034 break; 01035 } 01036 } 01037 if (lockpeer) 01038 AST_LIST_UNLOCK(&peers); 01039 if (!peer) { 01040 peer = realtime_peer(NULL, &sin); 01041 if (peer) { 01042 ast_copy_string(host, peer->name, len); 01043 if (ast_test_flag(peer, IAX_TEMPONLY)) 01044 destroy_peer(peer); 01045 res = 1; 01046 } 01047 } 01048 01049 return res; 01050 }
| static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 3279 of file chan_iax2.c.
References iax2_peer::addr, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_test_flag, and IAX_TRUNK.
Referenced by check_access().
03280 { 03281 struct iax2_peer *peer = NULL; 03282 int res = 0; 03283 03284 AST_LIST_LOCK(&peers); 03285 AST_LIST_TRAVERSE(&peers, peer, entry) { 03286 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 03287 (peer->addr.sin_port == sin.sin_port)) { 03288 res = ast_test_flag(peer, IAX_TRUNK); 03289 break; 03290 } 03291 } 03292 AST_LIST_UNLOCK(&peers); 03293 03294 return res; 03295 }
| static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 2971 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_verbose(), error(), ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, iaxs, iaxsl, option_verbose, PTR_TO_CALLNO, send_command_final(), ast_channel::tech_pvt, and VERBOSE_PREFIX_3.
02972 { 02973 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 02974 int alreadygone; 02975 struct iax_ie_data ied; 02976 memset(&ied, 0, sizeof(ied)); 02977 ast_mutex_lock(&iaxsl[callno]); 02978 if (callno && iaxs[callno]) { 02979 ast_log(LOG_DEBUG, "We're hanging up %s with cause %i now...\n", c->name, c->hangupcause); 02980 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 02981 /* Send the hangup unless we have had a transmission error or are already gone */ 02982 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 02983 if (!iaxs[callno]->error && !alreadygone) 02984 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 02985 /* Explicitly predestroy it */ 02986 iax2_predestroy(callno); 02987 /* If we were already gone to begin with, destroy us now */ 02988 if (alreadygone) { 02989 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name); 02990 iax2_destroy(callno); 02991 } 02992 } 02993 ast_mutex_unlock(&iaxsl[callno]); 02994 if (option_verbose > 2) 02995 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name); 02996 return 0; 02997 }
| static int iax2_indicate | ( | struct ast_channel * | c, | |
| int | condition, | |||
| const void * | data, | |||
| size_t | datalen | |||
| ) | [static] |
Definition at line 3226 of file chan_iax2.c.
References AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_FRAME_CONTROL, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), iaxs, iaxsl, option_debug, PTR_TO_CALLNO, send_command(), and ast_channel::tech_pvt.
03227 { 03228 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03229 struct chan_iax2_pvt *pvt; 03230 int res = 0; 03231 03232 if (option_debug && iaxdebug) 03233 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition); 03234 03235 ast_mutex_lock(&iaxsl[callno]); 03236 pvt = iaxs[callno]; 03237 if (!strcasecmp(pvt->mohinterpret, "passthrough")) { 03238 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 03239 ast_mutex_unlock(&iaxsl[callno]); 03240 return res; 03241 } 03242 03243 switch (condition) { 03244 case AST_CONTROL_HOLD: 03245 ast_moh_start(c, data, pvt->mohinterpret); 03246 break; 03247 case AST_CONTROL_UNHOLD: 03248 ast_moh_stop(c); 03249 break; 03250 default: 03251 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 03252 } 03253 03254 ast_mutex_unlock(&iaxsl[callno]); 03255 03256 return res; 03257 }
| 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 9617 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.
09618 { 09619 int res = 0; 09620 struct iax2_dpcache *dp; 09621 #if 0 09622 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 09623 #endif 09624 if ((priority != 1) && (priority != 2)) 09625 return 0; 09626 ast_mutex_lock(&dpcache_lock); 09627 dp = find_cache(chan, data, context, exten, priority); 09628 if (dp) { 09629 if (dp->flags & CACHE_FLAG_MATCHMORE) 09630 res= 1; 09631 } 09632 ast_mutex_unlock(&dpcache_lock); 09633 if (!dp) { 09634 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 09635 } 09636 return res; 09637 }
| static int iax2_no_debug | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 4501 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04502 { 04503 if (argc < 3 || argc > 4) 04504 return RESULT_SHOWUSAGE; 04505 iaxdebug = 0; 04506 ast_cli(fd, "IAX2 Debugging Disabled\n"); 04507 return RESULT_SUCCESS; 04508 }
| static int iax2_no_jb_debug | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 4519 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04520 { 04521 if (argc < 4 || argc > 5) 04522 return RESULT_SHOWUSAGE; 04523 jb_setoutput(jb_error_output, jb_warning_output, NULL); 04524 jb_debug_output("\n"); 04525 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 04526 return RESULT_SUCCESS; 04527 }
| static int iax2_no_trunk_debug | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 4510 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04511 { 04512 if (argc < 4 || argc > 5) 04513 return RESULT_SHOWUSAGE; 04514 iaxtrunkdebug = 0; 04515 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n"); 04516 return RESULT_SUCCESS; 04517 }
| static int iax2_poke_noanswer | ( | void * | data | ) | [static] |
Definition at line 7972 of file chan_iax2.c.
References __iax2_poke_noanswer(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
07973 { 07974 struct iax2_peer *peer = data; 07975 peer->pokeexpire = -1; 07976 #ifdef SCHED_MULTITHREADED 07977 if (schedule_action(__iax2_poke_noanswer, data)) 07978 #endif 07979 __iax2_poke_noanswer(data); 07980 return 0; 07981 }
| static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
| int | heldcall | |||
| ) | [static] |
Definition at line 7983 of file chan_iax2.c.
References iax2_peer::addr, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), iax2_peer::callno, DEFAULT_MAXMS, find_callno(), iax2_peer::historicms, iax2_destroy(), iax2_poke_noanswer(), IAX_COMMAND_POKE, iaxs, iaxsl, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, iax2_peer::maxms, NEW_FORCE, chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, sched, send_command(), and iax2_peer::sockfd.
Referenced by __iax2_poke_peer_s(), load_module(), reg_source_db(), reload_config(), and update_registry().
07984 { 07985 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 07986 /* IF we have no IP, or this isn't to be monitored, return 07987 immediately after clearing things out */ 07988 peer->lastms = 0; 07989 peer->historicms = 0; 07990 peer->pokeexpire = -1; 07991 peer->callno = 0; 07992 return 0; 07993 } 07994 if (peer->callno > 0) { 07995 ast_log(LOG_NOTICE, "Still have a callno...\n"); 07996 ast_mutex_lock(&iaxsl[peer->callno]); 07997 iax2_destroy(peer->callno); 07998 ast_mutex_unlock(&iaxsl[peer->callno]); 07999 } 08000 if (heldcall) 08001 ast_mutex_unlock(&iaxsl[heldcall]); 08002 peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, 0, peer->sockfd); 08003 if (heldcall) 08004 ast_mutex_lock(&iaxsl[heldcall]); 08005 if (peer->callno < 1) { 08006 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 08007 return -1; 08008 } 08009 08010 /* Speed up retransmission times for this qualify call */ 08011 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 08012 iaxs[peer->callno]->peerpoke = peer; 08013 08014 /* Remove any pending pokeexpire task */ 08015 if (peer->pokeexpire > -1) 08016 ast_sched_del(sched, peer->pokeexpire); 08017 08018 /* Queue up a new task to handle no reply */ 08019 /* If the host is already unreachable then use the unreachable interval instead */ 08020 if (peer->lastms < 0) { 08021 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer); 08022 } else 08023 peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer); 08024 08025 /* And send the poke */ 08026 send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1); 08027 08028 return 0; 08029 }
| static int iax2_poke_peer_s | ( | void * | data | ) | [static] |
Definition at line 5913 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
05914 { 05915 struct iax2_peer *peer = data; 05916 peer->pokeexpire = -1; 05917 #ifdef SCHED_MULTITHREADED 05918 if (schedule_action(__iax2_poke_peer_s, data)) 05919 #endif 05920 __iax2_poke_peer_s(data); 05921 return 0; 05922 }
| static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 1731 of file chan_iax2.c.
References ast_channel::_softhangup, ast_module_unref(), ast_queue_hangup(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_test_flag, iax2_destroy_helper(), IAX_ALREADYGONE, iaxs, chan_iax2_pvt::owner, and ast_channel::tech_pvt.
Referenced by iax2_hangup(), and send_command_final().
01732 { 01733 struct ast_channel *c; 01734 struct chan_iax2_pvt *pvt = iaxs[callno]; 01735 01736 if (!pvt) 01737 return -1; 01738 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 01739 iax2_destroy_helper(pvt); 01740 ast_set_flag(pvt, IAX_ALREADYGONE); 01741 } 01742 c = pvt->owner; 01743 if (c) { 01744 c->_softhangup |= AST_SOFTHANGUP_DEV; 01745 c->tech_pvt = NULL; 01746 ast_queue_hangup(c); 01747 pvt->owner = NULL; 01748 ast_module_unref(ast_module_info->self); 01749 } 01750 return 0; 01751 }
| static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 7698 of file chan_iax2.c.
References ast_cond_timedwait(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_tvadd(), iax2_process_thread_cleanup(), IAX_TYPE_DYNAMIC, iaxactivethreadcount, iaxdynamicthreadcount, insert_idle_thread(), and thread.
Referenced by find_idle_thread(), and start_network_thread().
07699 { 07700 struct iax2_thread *thread = data; 07701 struct timeval tv; 07702 struct timespec ts; 07703 int put_into_idle = 0; 07704 07705 ast_atomic_fetchadd_int(&iaxactivethreadcount,1); 07706 pthread_cleanup_push(iax2_process_thread_cleanup, data); 07707 for(;;) { 07708 /* Wait for something to signal us to be awake */ 07709 ast_mutex_lock(&thread->lock); 07710 07711 /* Put into idle list if applicable */ 07712 if (put_into_idle) 07713 insert_idle_thread(thread); 07714 07715 if (thread->type == IAX_TYPE_DYNAMIC) { 07716 /* Wait to be signalled or time out */ 07717 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 07718 ts.tv_sec = tv.tv_sec; 07719 ts.tv_nsec = tv.tv_usec * 1000; 07720 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 07721 ast_mutex_unlock(&thread->lock); 07722 AST_LIST_LOCK(&dynamic_list); 07723 AST_LIST_REMOVE(&dynamic_list, thread, list); 07724 iaxdynamicthreadcount--; 07725 AST_LIST_UNLOCK(&dynamic_list); 07726 break; /* exiting the main loop */ 07727 } 07728 } else { 07729 ast_cond_wait(&thread->cond, &thread->lock); 07730 } 07731 ast_mutex_unlock(&thread->lock); 07732 07733 /* Add ourselves to the active list now */ 07734 AST_LIST_LOCK(&active_list); 07735 AST_LIST_INSERT_HEAD(&active_list, thread, list); 07736 AST_LIST_UNLOCK(&active_list); 07737 07738 /* See what we need to do */ 07739 switch(thread->iostate) { 07740 case IAX_IOSTATE_READY: 07741 thread->actions++; 07742 thread->iostate = IAX_IOSTATE_PROCESSING; 07743 socket_process(thread); 07744 break; 07745 case IAX_IOSTATE_SCHEDREADY: 07746 thread->actions++; 07747 thread->iostate = IAX_IOSTATE_PROCESSING; 07748 #ifdef SCHED_MULTITHREADED 07749 thread->schedfunc(thread->scheddata); 07750 #endif 07751 break; 07752 } 07753 time(&thread->checktime); 07754 thread->iostate = IAX_IOSTATE_IDLE; 07755 #ifdef DEBUG_SCHED_MULTITHREAD 07756 thread->curfunc[0]='\0'; 07757 #endif 07758 07759 /* Now... remove ourselves from the active list, and return to the idle list */ 07760 AST_LIST_LOCK(&active_list); 07761 AST_LIST_REMOVE(&active_list, thread, list); 07762 AST_LIST_UNLOCK(&active_list); 07763 07764 /* Go back into our respective list */ 07765 put_into_idle = 1; 07766 } 07767 07768 /* I am exiting here on my own volition, I need to clean up my own data structures 07769 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 07770 */ 07771 pthread_cleanup_pop(1); 07772 07773 return NULL; 07774 }
| static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 7689 of file chan_iax2.c.
References ast_cond_destroy(), ast_mutex_destroy(), free, iaxactivethreadcount, and thread.
Referenced by iax2_process_thread().
07690 { 07691 struct iax2_thread *thread = data; 07692 ast_mutex_destroy(&thread->lock); 07693 ast_cond_destroy(&thread->cond); 07694 free(thread); 07695 ast_atomic_dec_and_test(&iaxactivethreadcount); 07696 }
| static int iax2_prov_cmd | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 7931 of file chan_iax2.c.
References ast_cli(), iax2_provision(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
07932 { 07933 int force = 0; 07934 int res; 07935 if (argc < 4) 07936 return RESULT_SHOWUSAGE; 07937 if ((argc > 4)) { 07938 if (!strcasecmp(argv[4], "forced")) 07939 force = 1; 07940 else 07941 return RESULT_SHOWUSAGE; 07942 } 07943 res = iax2_provision(NULL, -1, argv[2], argv[3], force); 07944 if (res < 0) 07945 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]); 07946 else if (res < 1) 07947 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]); 07948 else 07949 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : ""); 07950 return RESULT_SUCCESS; 07951 }
| static char* iax2_prov_complete_template_3rd | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 7833 of file chan_iax2.c.
References iax_prov_complete_template().
07834 { 07835 if (pos != 3) 07836 return NULL; 07837 return iax_prov_complete_template(line, word, pos, state); 07838 }
| static int iax2_provision | ( | struct sockaddr_in * | end, | |
| int | sockfd, | |||
| char * | dest, | |||
| const char * | template, | |||
| int | force | |||
| ) | [static] |
Definition at line 7840 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), ast_set_flag, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, create_addr(), find_callno(), IAX_COMMAND_PROVISION, iax_ie_append_raw(), IAX_IE_PROVISIONING, IAX_PROVISION, iax_provision_build(), iaxs, iaxsl, NEW_FORCE, option_debug, iax_ie_data::pos, sched, and send_command().
Referenced by check_provisioning(), iax2_prov_app(), and iax2_prov_cmd().
07841 { 07842 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 07843 is found for template */ 07844 struct iax_ie_data provdata; 07845 struct iax_ie_data ied; 07846 unsigned int sig; 07847 struct sockaddr_in sin; 07848 int callno; 07849 struct create_addr_info cai; 07850 07851 memset(&cai, 0, sizeof(cai)); 07852 07853 if (option_debug) 07854 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template); 07855 07856 if (iax_provision_build(&provdata, &sig, template, force)) { 07857 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template); 07858 return 0; 07859 } 07860 07861 if (end) { 07862 memcpy(&sin, end, sizeof(sin)); 07863 cai.sockfd = sockfd; 07864 } else if (create_addr(dest, &sin, &cai)) 07865 return -1; 07866 07867 /* Build the rest of the message */ 07868 memset(&ied, 0, sizeof(ied)); 07869 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 07870 07871 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd); 07872 if (!callno) 07873 return -1; 07874 07875 ast_mutex_lock(&iaxsl[callno]); 07876 if (iaxs[callno]) { 07877 /* Schedule autodestruct in case they don't ever give us anything back */ 07878 if (iaxs[callno]->autoid > -1) 07879 ast_sched_del(sched, iaxs[callno]->autoid); 07880 iaxs[callno]->autoid = ast_sched_add(sched, 15000, auto_hangup, (void *)(long)callno); 07881 ast_set_flag(iaxs[callno], IAX_PROVISION); 07882 /* Got a call number now, so go ahead and send the provisioning information */ 07883 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 07884 } 07885 ast_mutex_unlock(&iaxsl[callno]); 07886 07887 return 1; 07888 }
| static int iax2_prune_realtime | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 1925 of file chan_iax2.c.
References ast_cli(), ast_set_flag, ast_test_flag, expire_registry(), find_peer(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, reload_config(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01926 { 01927 struct iax2_peer *peer; 01928 01929 if (argc != 4) 01930 return RESULT_SHOWUSAGE; 01931 if (!strcmp(argv[3],"all")) { 01932 reload_config(); 01933 ast_cli(fd, "OK cache is flushed.\n"); 01934 } else if ((peer = find_peer(argv[3], 0))) { 01935 if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 01936 ast_set_flag(peer, IAX_RTAUTOCLEAR); 01937 expire_registry((void*)peer->name); 01938 ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]); 01939 } else { 01940 ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]); 01941 } 01942 } else { 01943 ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]); 01944 } 01945 01946 return RESULT_SUCCESS; 01947 }
| static int iax2_queue_frame | ( | int | callno, | |
| struct ast_frame * | f | |||
| ) | [static] |
Definition at line 1308 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), f, iaxs, and iaxsl.
Referenced by __attempt_transmit(), __auto_congest(), __do_deliver(), and __get_from_jb().
01309 { 01310 /* Assumes lock for callno is already held... */ 01311 for (;;) { 01312 if (iaxs[callno] && iaxs[callno]->owner) { 01313 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01314 /* Avoid deadlock by pausing and trying again */ 01315 ast_mutex_unlock(&iaxsl[callno]); 01316 usleep(1); 01317 ast_mutex_lock(&iaxsl[callno]); 01318 } else { 01319 ast_queue_frame(iaxs[callno]->owner, f); 01320 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01321 break; 01322 } 01323 } else 01324 break; 01325 } 01326 return 0; 01327 }
| static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3025 of file chan_iax2.c.
References ast_log(), ast_null_frame, and LOG_NOTICE.
03026 { 03027 ast_log(LOG_NOTICE, "I should never be called!\n"); 03028 return &ast_null_frame; 03029 }
| static int iax2_register | ( | char * | value, | |
| int | lineno | |||
| ) | [static] |
Definition at line 5449 of file chan_iax2.c.
References ast_calloc, ast_dnsmgr_lookup(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), copy(), free, hostname, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, LOG_WARNING, and strsep().
Referenced by set_config().
05450 { 05451 struct iax2_registry *reg; 05452 char copy[256]; 05453 char *username, *hostname, *secret; 05454 char *porta; 05455 char *stringp=NULL; 05456 05457 if (!value) 05458 return -1; 05459 ast_copy_string(copy, value, sizeof(copy)); 05460 stringp=copy; 05461 username = strsep(&stringp, "@"); 05462 hostname = strsep(&stringp, "@"); 05463 if (!hostname) { 05464 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 05465 return -1; 05466 } 05467 stringp=username; 05468 username = strsep(&stringp, ":"); 05469 secret = strsep(&stringp, ":"); 05470 stringp=hostname; 05471 hostname = strsep(&stringp, ":"); 05472 porta = strsep(&stringp, ":"); 05473 05474 if (porta && !atoi(porta)) { 05475 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 05476 return -1; 05477 } 05478 if (!(reg = ast_calloc(1, sizeof(*reg)))) 05479 return -1; 05480 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) { 05481 free(reg); 05482 return -1; 05483 } 05484 ast_copy_string(reg->username, username, sizeof(reg->username)); 05485 if (secret) 05486 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 05487 reg->expire = -1; 05488 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 05489 reg->addr.sin_family = AF_INET; 05490 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 05491 AST_LIST_LOCK(®istrations); 05492 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 05493 AST_LIST_UNLOCK(®istrations); 05494 05495 return 0; 05496 }
| static int iax2_reload | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 9345 of file chan_iax2.c.
References reload_config().
09346 { 09347 return reload_config(); 09348 }
| static struct ast_channel * iax2_request | ( | const char * | type, | |
| int | format, | |||
| void * | data, | |||
| int * | cause | |||
| ) | [static] |
Definition at line 8041 of file chan_iax2.c.
References ast_best_codec(), AST_CAUSE_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_flags, ast_getformatname(), ast_hangup(), ast_iax2_new(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DOWN, ast_strdupa, ast_string_field_set, ast_test_flag, ast_translator_best_choice(), create_addr(), find_callno(), fmt, globalflags, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, iaxsl, LOG_WARNING, make_trunk(), chan_iax2_pvt::maxtime, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), ast_channel::readformat, and ast_channel::writeformat.
08042 { 08043 int callno; 08044 int res; 08045 int fmt, native; 08046 struct sockaddr_in sin; 08047 struct ast_channel *c; 08048 struct parsed_dial_string pds; 08049 struct create_addr_info cai; 08050 char *tmpstr; 08051 08052 memset(&pds, 0, sizeof(pds)); 08053 tmpstr = ast_strdupa(data); 08054 parse_dial_string(tmpstr, &pds); 08055 08056 memset(&cai, 0, sizeof(cai)); 08057 cai.capability = iax2_capability; 08058 08059 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08060 08061 if (!pds.peer) { 08062 ast_log(LOG_WARNING, "No peer given\n"); 08063 return NULL; 08064 } 08065 08066 08067 /* Populate our address from the given */ 08068 if (create_addr(pds.peer, &sin, &cai)) { 08069 *cause = AST_CAUSE_UNREGISTERED; 08070 return NULL; 08071 } 08072 08073 if (pds.port) 08074 sin.sin_port = htons(atoi(pds.port)); 08075 08076 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd); 08077 if (callno < 1) { 08078 ast_log(LOG_WARNING, "Unable to create call\n"); 08079 *cause = AST_CAUSE_CONGESTION; 08080 return NULL; 08081 } 08082 08083 ast_mutex_lock(&iaxsl[callno]); 08084 08085 /* If this is a trunk, update it now */ 08086 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 08087 if (ast_test_flag(&cai, IAX_TRUNK)) 08088 callno = make_trunk(callno, 1); 08089 iaxs[callno]->maxtime = cai.maxtime; 08090 if (cai.found) 08091 ast_string_field_set(iaxs[callno], host, pds.peer); 08092 08093 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 08094 08095 ast_mutex_unlock(&iaxsl[callno]); 08096 08097 if (c) { 08098 /* Choose a format we can live with */ 08099 if (c->nativeformats & format) 08100 c->nativeformats &= format; 08101 else { 08102 native = c->nativeformats; 08103 fmt = format; 08104 res = ast_translator_best_choice(&fmt, &native); 08105 if (res < 0) { 08106 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 08107 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 08108 ast_hangup(c); 08109 return NULL; 08110 } 08111 c->nativeformats = native; 08112 } 08113 c->readformat = ast_best_codec(c->nativeformats); 08114 c->writeformat = c->readformat; 08115 } 08116 08117 return c; 08118 }
| 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 3826 of file chan_iax2.c.
References iax_frame::af, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_test_flag, calc_timestamp(), ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, chan_iax2_pvt::callno, iax_frame::callno, compress_subclass(), ast_iax2_full_hdr::csub, iax_frame::data, ast_frame::data, ast_frame::datalen, iax_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, encrypt_frame(), f, iax_frame::final, ast_frame::frametype, iax2_transmit(), iax2_trunk_queue(), IAX_COMMAND_ACK, IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_showframe(), IAX_TRUNK, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, chan_iax2_pvt::lastsent, LOG_WARNING, MAX_RETRY_TIME, MIN_RETRY_TIME, ast_iax2_full_hdr::oseqno, chan_iax2_pvt::oseqno, iax_frame::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, iax_frame::retries, iax_frame::retrytime, ast_iax2_full_hdr::scallno, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, iax_frame::transfer, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, ast_iax2_mini_hdr::ts, ast_iax2_video_hdr::ts, ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_full_hdr::type, and ast_iax2_video_hdr::zeros.
Referenced by __send_command(), iax2_write(), and socket_process().
03827 { 03828 /* Queue a packet for delivery on a given private structure. Use "ts" for 03829 timestamp, or calculate if ts is 0. Send immediately without retransmission 03830 or delayed, with retransmission */ 03831 struct ast_iax2_full_hdr *fh; 03832 struct ast_iax2_mini_hdr *mh; 03833 struct ast_iax2_video_hdr *vh; 03834 struct { 03835 struct iax_frame fr2; 03836 unsigned char buffer[4096]; 03837 } frb; 03838 struct iax_frame *fr; 03839 int res; 03840 int sendmini=0; 03841 unsigned int lastsent; 03842 unsigned int fts; 03843 03844 if (!pvt) { 03845 ast_log(LOG_WARNING, "No private structure for packet?\n"); 03846 return -1; 03847 } 03848 03849 lastsent = pvt->lastsent; 03850 03851 /* Calculate actual timestamp */ 03852 fts = calc_timestamp(pvt, ts, f); 03853 03854 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 03855 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 03856 * increment the "predicted timestamps" for voice, if we're predecting */ 03857 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 03858 return 0; 03859 03860 03861 if ((ast_test_flag(pvt, IAX_TRUNK) || 03862 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 03863 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 03864 /* High two bytes are the same on timestamp, or sending on a trunk */ && 03865 (f->frametype == AST_FRAME_VOICE) 03866 /* is a voice frame */ && 03867 (f->subclass == pvt->svoiceformat) 03868 /* is the same type */ ) { 03869 /* Force immediate rather than delayed transmission */ 03870 now = 1; 03871 /* Mark that mini-style frame is appropriate */ 03872 sendmini = 1; 03873 } 03874 if (((fts & 0xFFFF8000L) == (lastsent & 0xFFFF8000L)) && 03875 (f->frametype == AST_FRAME_VIDEO) && 03876 ((f->subclass & ~0x1) == pvt->svideoformat)) { 03877 now = 1; 03878 sendmini = 1; 03879 } 03880 /* Allocate an iax_frame */ 03881 if (now) { 03882 fr = &frb.fr2; 03883 } else 03884 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)); 03885 if (!fr) { 03886 ast_log(LOG_WARNING, "Out of memory\n"); 03887 return -1; 03888 } 03889 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 03890 iax_frame_wrap(fr, f); 03891 03892 fr->ts = fts; 03893 fr->callno = pvt->callno; 03894 fr->transfer = transfer; 03895 fr->final = final; 03896 if (!sendmini) { 03897 /* We need a full frame */ 03898 if (seqno > -1) 03899 fr->oseqno = seqno; 03900 else 03901 fr->oseqno = pvt->oseqno++; 03902 fr->iseqno = pvt->iseqno; 03903 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr)); 03904 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 03905 fh->ts = htonl(fr->ts); 03906 fh->oseqno = fr->oseqno; 03907 if (transfer) { 03908 fh->iseqno = 0; 03909 } else 03910 fh->iseqno = fr->iseqno; 03911 /* Keep track of the last thing we've acknowledged */ 03912 if (!transfer) 03913 pvt->aseqno = fr->iseqno; 03914 fh->type = fr->af.frametype & 0xFF; 03915 if (fr->af.frametype == AST_FRAME_VIDEO) 03916 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 03917 else 03918 fh->csub = compress_subclass(fr->af.subclass); 03919 if (transfer) { 03920 fr->dcallno = pvt->transfercallno; 03921 } else 03922 fr->dcallno = pvt->peercallno; 03923 fh->dcallno = htons(fr->dcallno); 03924 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 03925 fr->data = fh; 03926 fr->retries = 0; 03927 /* Retry after 2x the ping time has passed */ 03928 fr->retrytime = pvt->pingtime * 2; 03929 if (fr->retrytime < MIN_RETRY_TIME) 03930 fr->retrytime = MIN_RETRY_TIME; 03931 if (fr->retrytime > MAX_RETRY_TIME) 03932 fr->retrytime = MAX_RETRY_TIME; 03933 /* Acks' don't get retried */ 03934 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 03935 fr->retries = -1; 03936 else if (f->frametype == AST_FRAME_VOICE) 03937 pvt->svoiceformat = f->subclass; 03938 else if (f->frametype == AST_FRAME_VIDEO) 03939 pvt->svideoformat = f->subclass & ~0x1; 03940 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 03941 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 03942 if (iaxdebug) { 03943 if (fr->transfer) 03944 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 03945 else 03946 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 03947 } 03948 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 03949 } else 03950 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 03951 } 03952 03953 if (now) { 03954 res = send_packet(fr); 03955 } else 03956 res = iax2_transmit(fr); 03957 } else { 03958 if (ast_test_flag(pvt, IAX_TRUNK)) { 03959 iax2_trunk_queue(pvt, fr); 03960 res = 0; 03961 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 03962 /* Video frame have no sequence number */ 03963 fr->oseqno = -1; 03964 fr->iseqno = -1; 03965 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr)); 03966 vh->zeros = 0; 03967 vh->callno = htons(0x8000 | fr->callno); 03968 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 03969 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 03970 fr->data = vh; 03971 fr->retries = -1; 03972 res = send_packet(fr); 03973 } else { 03974 /* Mini-frames have no sequence number */ 03975 fr->oseqno = -1; 03976 fr->iseqno = -1; 03977 /* Mini frame will do */ 03978 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr)); 03979 mh->callno = htons(fr->callno); 03980 mh->ts = htons(fr->ts & 0xFFFF); 03981 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 03982 fr->data = mh; 03983 fr->retries = -1; 03984 if (pvt->transferring == TRANSFER_MEDIAPASS) 03985 fr->transfer = 1; 03986 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 03987 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 03988 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 03989 } else 03990 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 03991 } 03992 res = send_packet(fr); 03993 } 03994 } 03995 return res; 03996 }
| static int iax2_sendhtml | ( | struct ast_channel * | c, | |
| int | subclass, | |||
| const char * | data, | |||
| int | datalen | |||
| ) | [static] |
Definition at line 2439 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02440 { 02441 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 02442 }
| static int iax2_sendimage | ( | struct ast_channel * | c, | |
| struct ast_frame * | img | |||
| ) | [static] |
Definition at line 2434 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.
02435 { 02436 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1); 02437 }
| static int iax2_sendtext | ( | struct ast_channel * | c, | |
| const char * | text | |||
| ) | [static] |
Definition at line 2427 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02428 { 02429 02430 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 02431 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 02432 }
| static int iax2_setoption | ( | struct ast_channel * | c, | |
| int | option, | |||
| void * | data, | |||
| int | datalen | |||
| ) | [static] |
Definition at line 2999 of file chan_iax2.c.
References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_malloc, AST_OPTION_FLAG_REQUEST, AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, free, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03000 { 03001 struct ast_option_header *h; 03002 int res; 03003 03004 switch (option) { 03005 case AST_OPTION_TXGAIN: 03006 case AST_OPTION_RXGAIN: 03007 /* these two cannot be sent, because they require a result */ 03008 errno = ENOSYS; 03009 return -1; 03010 default: 03011 if (!(h = ast_malloc(datalen + sizeof(*h)))) 03012 return -1; 03013 03014 h->flag = AST_OPTION_FLAG_REQUEST; 03015 h->option = htons(option); 03016 memcpy(h->data, data, datalen); 03017 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 03018 AST_CONTROL_OPTION, 0, (unsigned char *) h, 03019 datalen + sizeof(*h), -1); 03020 free(h); 03021 return res; 03022 } 03023 }
| static int iax2_show_cache | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 2126 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.
02127 { 02128 struct iax2_dpcache *dp; 02129 char tmp[1024], *pc; 02130 int s; 02131 int x,y; 02132 struct timeval tv; 02133 gettimeofday(&tv, NULL); 02134 ast_mutex_lock(&dpcache_lock); 02135 dp = dpcache; 02136 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 02137 while(dp) { 02138 s = dp->expiry.tv_sec - tv.tv_sec; 02139 tmp[0] = '\0'; 02140 if (dp->flags & CACHE_FLAG_EXISTS) 02141 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 02142 if (dp->flags & CACHE_FLAG_NONEXISTENT) 02143 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 02144 if (dp->flags & CACHE_FLAG_CANEXIST) 02145 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 02146 if (dp->flags & CACHE_FLAG_PENDING) 02147 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 02148 if (dp->flags & CACHE_FLAG_TIMEOUT) 02149 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 02150 if (dp->flags & CACHE_FLAG_TRANSMITTED) 02151 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 02152 if (dp->flags & CACHE_FLAG_MATCHMORE) 02153 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 02154 if (dp->flags & CACHE_FLAG_UNKNOWN) 02155 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 02156 /* Trim trailing pipe */ 02157 if (!ast_strlen_zero(tmp)) 02158 tmp[strlen(tmp) - 1] = '\0'; 02159 else 02160 ast_copy_string(tmp, "(none)", sizeof(tmp)); 02161 y=0; 02162 pc = strchr(dp->peercontext, '@'); 02163 if (!pc) 02164 pc = dp->peercontext; 02165 else 02166 pc++; 02167 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 02168 if (dp->waiters[x] > -1) 02169 y++; 02170 if (s > 0) 02171 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 02172 else 02173 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 02174 dp = dp->next; 02175 } 02176 ast_mutex_unlock(&dpcache_lock); 02177 return RESULT_SUCCESS; 02178 }
| static int iax2_show_channels | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 4339 of file chan_iax2.c.
References ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, jb_info::current, iax_rr::delay, FORMAT, FORMAT2, IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), jb_info::jitter, jb_info::min, chan_iax2_pvt::remote_rr, RESULT_SHOWUSAGE, RESULT_SUCCESS, and S_OR.
04340 { 04341 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n" 04342 #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" 04343 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 04344 int x; 04345 int numchans = 0; 04346 04347 if (argc != 3) 04348 return RESULT_SHOWUSAGE; 04349 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format"); 04350 for (x=0;x<IAX_MAX_CALLS;x++) { 04351 ast_mutex_lock(&iaxsl[x]); 04352 if (iaxs[x]) { 04353 int lag, jitter, localdelay; 04354 jb_info jbinfo; 04355 04356 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 04357 jb_getinfo(iaxs[x]->jb, &jbinfo); 04358 jitter = jbinfo.jitter; 04359 localdelay = jbinfo.current - jbinfo.min; 04360 } else { 04361 jitter = -1; 04362 localdelay = 0; 04363 } 04364 lag = iaxs[x]->remote_rr.delay; 04365 ast_cli(fd, FORMAT, 04366 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 04367 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 04368 S_OR(iaxs[x]->username, "(None)"), 04369 iaxs[x]->callno, iaxs[x]->peercallno, 04370 iaxs[x]->oseqno, iaxs[x]->iseqno, 04371 lag, 04372 jitter, 04373 localdelay, 04374 ast_getformatname(iaxs[x]->voiceformat) ); 04375 numchans++; 04376 } 04377 ast_mutex_unlock(&iaxsl[x]); 04378 } 04379 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04380 return RESULT_SUCCESS; 04381 #undef FORMAT 04382 #undef FORMAT2 04383 #undef FORMATB 04384 }
| static int iax2_show_firmware | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 4250 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.
04251 { 04252 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" 04253 #if !defined(__FreeBSD__) 04254 #define FORMAT "%-15.15s %-15d %-15d\n" 04255 #else /* __FreeBSD__ */ 04256 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */ 04257 #endif /* __FreeBSD__ */ 04258 struct iax_firmware *cur; 04259 if ((argc != 3) && (argc != 4)) 04260 return RESULT_SHOWUSAGE; 04261 ast_mutex_lock(&waresl.lock); 04262 04263 ast_cli(fd, FORMAT2, "Device", "Version", "Size"); 04264 for (cur = waresl.wares;cur;cur = cur->next) { 04265 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 04266 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version), 04267 (int)ntohl(cur->fwh->datalen)); 04268 } 04269 ast_mutex_unlock(&waresl.lock); 04270 return RESULT_SUCCESS; 04271 #undef FORMAT 04272 #undef FORMAT2 04273 }
| static int iax2_show_netstats | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 4462 of file chan_iax2.c.
References ast_cli(), ast_cli_netstats(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
04463 { 04464 int numchans = 0; 04465 if (argc != 3) 04466 return RESULT_SHOWUSAGE; 04467 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 04468 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n"); 04469 numchans = ast_cli_netstats(NULL, fd, 1); 04470 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 04471 return RESULT_SUCCESS; 04472 }
| static int iax2_show_peer | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Show one peer in detail.
Definition at line 2018 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, destroy_peer(), iax2_peer::expire, find_peer(), iax2_peer::ha, IAX_DYNAMIC, IAX_TEMPONLY, peer_status(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax2_peer::prefs, RESULT_SHOWUSAGE, RESULT_SUCCESS, and iax2_peer::smoothing.
02019 { 02020 char status[30]; 02021 char cbuf[256]; 02022 struct iax2_peer *peer; 02023 char codec_buf[512]; 02024 int x = 0, codec = 0, load_realtime = 0; 02025 02026 if (argc < 4) 02027 return RESULT_SHOWUSAGE; 02028 02029 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 02030 02031 peer = find_peer(argv[3], load_realtime); 02032 if (peer) { 02033 ast_cli(fd,"\n\n"); 02034 ast_cli(fd, " * Name : %s\n", peer->name); 02035 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 02036 ast_cli(fd, " Context : %s\n", peer->context); 02037 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 02038 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No"); 02039 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 02040 ast_cli(fd, " Expire : %d\n", peer->expire); 02041 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 02042 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)); 02043 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 02044 ast_cli(fd, " Username : %s\n", peer->username); 02045 ast_cli(fd, " Codecs : "); 02046 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 02047 ast_cli(fd, "%s\n", codec_buf); 02048 02049 ast_cli(fd, " Codec Order : ("); 02050 for(x = 0; x < 32 ; x++) { 02051 codec = ast_codec_pref_index(&peer->prefs,x); 02052 if(!codec) 02053 break; 02054 ast_cli(fd, "%s", ast_getformatname(codec)); 02055 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 02056 ast_cli(fd, "|"); 02057 } 02058 02059 if (!x) 02060 ast_cli(fd, "none"); 02061 ast_cli(fd, ")\n"); 02062 02063 ast_cli(fd, " Status : "); 02064 peer_status(peer, status, sizeof(status)); 02065 ast_cli(fd, "%s\n",status); 02066 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 02067 ast_cli(fd,"\n"); 02068 if (ast_test_flag(peer, IAX_TEMPONLY)) 02069 destroy_peer(peer); 02070 } else { 02071 ast_cli(fd,"Peer %s not found.\n", argv[3]); 02072 ast_cli(fd,"\n"); 02073 } 02074 02075 return RESULT_SUCCESS; 02076 }
| static int iax2_show_peers | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 4239 of file chan_iax2.c.
References __iax2_show_peers().
04240 { 04241 return __iax2_show_peers(0, fd, NULL, argc, argv); 04242 }
| static int iax2_show_registry | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 4311 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.
04312 { 04313 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 04314 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 04315 struct iax2_registry *reg = NULL; 04316 04317 char host[80]; 04318 char perceived[80]; 04319 if (argc != 3) 04320 return RESULT_SHOWUSAGE; 04321 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 04322 AST_LIST_LOCK(®istrations); 04323 AST_LIST_TRAVERSE(®istrations, reg, entry) { 04324 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 04325 if (reg->us.sin_addr.s_addr) 04326 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 04327 else 04328 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 04329 ast_cli(fd, FORMAT, host, 04330 (reg->dnsmgr) ? "Y" : "N", 04331 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 04332 } 04333 AST_LIST_UNLOCK(®istrations); 04334 return RESULT_SUCCESS; 04335 #undef FORMAT 04336 #undef FORMAT2 04337 }
| static int iax2_show_stats | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 2100 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.
02101 { 02102 struct iax_frame *cur; 02103 int cnt = 0, dead=0, final=0; 02104 02105 if (argc != 3) 02106 return RESULT_SHOWUSAGE; 02107 02108 AST_LIST_LOCK(&iaxq.queue); 02109 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 02110 if (cur->retries < 0) 02111 dead++; 02112 if (cur->final) 02113 final++; 02114 cnt++; 02115 } 02116 AST_LIST_UNLOCK(&iaxq.queue); 02117 02118 ast_cli(fd, " IAX Statistics\n"); 02119 ast_cli(fd, "---------------------\n"); 02120 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 02121 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 02122 02123 return RESULT_SUCCESS; 02124 }
| static int iax2_show_threads | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 4180 of file chan_iax2.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, IAX_TYPE_DYNAMIC, iaxthreadcount, RESULT_SHOWUSAGE, RESULT_SUCCESS, t, thread, and type.
04181 { 04182 struct iax2_thread *thread = NULL; 04183 time_t t; 04184 int threadcount = 0, dynamiccount = 0; 04185 char type; 04186 04187 if (argc != 3) 04188 return RESULT_SHOWUSAGE; 04189 04190 ast_cli(fd, "IAX2 Thread Information\n"); 04191 time(&t); 04192 ast_cli(fd, "Idle Threads:\n"); 04193 AST_LIST_LOCK(&idle_list); 04194 AST_LIST_TRAVERSE(&idle_list, thread, list) { 04195 #ifdef DEBUG_SCHED_MULTITHREAD 04196 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04197 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04198 #else 04199 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04200 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04201 #endif 04202 threadcount++; 04203 } 04204 AST_LIST_UNLOCK(&idle_list); 04205 ast_cli(fd, "Active Threads:\n"); 04206 AST_LIST_LOCK(&active_list); 04207 AST_LIST_TRAVERSE(&active_list, thread, list) { 04208 if (thread->type == IAX_TYPE_DYNAMIC) 04209 type = 'D'; 04210 else 04211 type = 'P'; 04212 #ifdef DEBUG_SCHED_MULTITHREAD 04213 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 04214 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04215 #else 04216 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 04217 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04218 #endif 04219 threadcount++; 04220 } 04221 AST_LIST_UNLOCK(&active_list); 04222 ast_cli(fd, "Dynamic Threads:\n"); 04223 AST_LIST_LOCK(&dynamic_list); 04224 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 04225 #ifdef DEBUG_SCHED_MULTITHREAD 04226 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04227 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04228 #else 04229 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04230 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04231 #endif 04232 dynamiccount++; 04233 } 04234 AST_LIST_UNLOCK(&dynamic_list); 04235 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 04236 return RESULT_SUCCESS; 04237 }
| static int iax2_show_users | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 3998 of file chan_iax2.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, 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, and RESULT_SUCCESS.
03999 { 04000 regex_t regexbuf; 04001 int havepattern = 0; 04002 04003 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 04004 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 04005 04006 struct iax2_user *user = NULL; 04007 char auth[90]; 04008 char *pstr = ""; 04009 04010 switch (argc) { 04011 case 5: 04012 if (!strcasecmp(argv[3], "like")) { 04013 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04014 return RESULT_SHOWUSAGE; 04015 havepattern = 1; 04016 } else 04017 return RESULT_SHOWUSAGE; 04018 case 3: 04019 break; 04020 default: 04021 return RESULT_SHOWUSAGE; 04022 } 04023 04024 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 04025 AST_LIST_LOCK(&users); 04026 AST_LIST_TRAVERSE(&users, user, entry) { 04027 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 04028 continue; 04029 04030 if (!ast_strlen_zero(user->secret)) { 04031 ast_copy_string(auth,user->secret,sizeof(auth)); 04032 } else if (!ast_strlen_zero(user->inkeys)) { 04033 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 04034 } else 04035 ast_copy_string(auth, "-no secret-", sizeof(auth)); 04036 04037 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 04038 pstr = "REQ Only"; 04039 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 04040 pstr = "Disabled"; 04041 else 04042 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 04043 04044 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 04045 user->contexts ? user->contexts->context : context, 04046 user->ha ? "Yes" : "No", pstr); 04047 04048 } 04049 AST_LIST_UNLOCK(&users); 04050 04051 if (havepattern) 04052 regfree(®exbuf); 04053 04054 return RESULT_SUCCESS; 04055 #undef FORMAT 04056 #undef FORMAT2 04057 }
| static int iax2_start_transfer | ( | unsigned short | callno0, | |
| unsigned short | callno1, | |||
| int | mediaonly | |||
| ) | [static] |
Definition at line 3031 of file chan_iax2.c.
References AST_FRAME_IAX, ast_random(), IAX_COMMAND_TXREQ, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), IAX_IE_CALLNO, IAX_IE_TRANSFERID, iaxs, send_command(), TRANSFER_BEGIN, TRANSFER_MBEGIN, and chan_iax2_pvt::transferring.
03032 { 03033 int res; 03034 struct iax_ie_data ied0; 03035 struct iax_ie_data ied1; 03036 unsigned int transferid = (unsigned int)ast_random(); 03037 memset(&ied0, 0, sizeof(ied0)); 03038 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 03039 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 03040 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 03041 03042 memset(&ied1, 0, sizeof(ied1)); 03043 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 03044 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 03045 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 03046 03047 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 03048 if (res) 03049 return -1; 03050 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 03051 if (res) 03052 return -1; 03053 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03054 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03055 return 0; 03056 }
| static int iax2_test_losspct | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 1949 of file chan_iax2.c.
References RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01950 { 01951 if (argc != 4) 01952 return RESULT_SHOWUSAGE; 01953 01954 test_losspct = atoi(argv[3]); 01955 01956 return RESULT_SUCCESS; 01957 }
| static int iax2_transfer | ( | struct ast_channel * | c, | |
| const char * | dest | |||
| ) | [static] |
Definition at line 3259 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, option_debug, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03260 { 03261 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03262 struct iax_ie_data ied; 03263 char tmp[256], *context; 03264 ast_copy_string(tmp, dest, sizeof(tmp)); 03265 context = strchr(tmp, '@'); 03266 if (context) { 03267 *context = '\0'; 03268 context++; 03269 } 03270 memset(&ied, 0, sizeof(ied)); 03271 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 03272 if (context) 03273 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 03274 if (option_debug) 03275 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest); 03276 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 03277 }
| static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2399 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, iaxq, iax_frame::sentyet, and signal_condition().
Referenced by iax2_send().
02400 { 02401 /* Lock the queue and place this packet at the end */ 02402 /* By setting this to 0, the network thread will send it for us, and 02403 queue retransmission if necessary */ 02404 fr->sentyet = 0; 02405 AST_LIST_LOCK(&iaxq.queue); 02406 AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list); 02407 iaxq.count++; 02408 AST_LIST_UNLOCK(&iaxq.queue); 02409 /* Wake up the network and scheduler thread */ 02410 pthread_kill(netthreadid, SIGURG); 02411 signal_condition(&sched_lock, &sched_cond); 02412 return 0; 02413 }
| static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
| struct timeval * | now | |||
| ) | [inline, static] |
Definition at line 5967 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
05968 { 05969 /* Drop when trunk is about 5 seconds idle */ 05970 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 05971 return 1; 05972 return 0; 05973 }
| static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_frame * | fr | |||
| ) | [static] |
Definition at line 3601 of file chan_iax2.c.
References iax2_trunk_peer::addr, chan_iax2_pvt::addr, iax_frame::af, ast_inet_ntoa(), ast_log(), ast_mutex_unlock(), ast_realloc, ast_test_flag, ast_iax2_meta_trunk_entry::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, iax2_trunk_peer::calls, DEFAULT_TRUNKDATA, f, find_tpeer(), globalflags, IAX2_TRUNK_PREFACE, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, MAX_TRUNKDATA, ast_iax2_meta_trunk_mini::mini, chan_iax2_pvt::sockfd, iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdataalloc, iax2_trunk_peer::trunkdatalen, iax_frame::ts, and ast_iax2_mini_hdr::ts.
Referenced by iax2_send().
03602 { 03603 struct ast_frame *f; 03604 struct iax2_trunk_peer *tpeer; 03605 void *tmp, *ptr; 03606 struct ast_iax2_meta_trunk_entry *met; 03607 struct ast_iax2_meta_trunk_mini *mtm; 03608 03609 f = &fr->af; 03610 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 03611 if (tpeer) { 03612 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 03613 /* Need to reallocate space */ 03614 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) { 03615 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 03616 ast_mutex_unlock(&tpeer->lock); 03617 return -1; 03618 } 03619 03620 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 03621 tpeer->trunkdata = tmp; 03622 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); 03623 } else { 03624 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)); 03625 ast_mutex_unlock(&tpeer->lock); 03626 return -1; 03627 } 03628 } 03629 03630 /* Append to meta frame */ 03631 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 03632 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 03633 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 03634 mtm->len = htons(f->datalen); 03635 mtm->mini.callno = htons(pvt->callno); 03636 mtm->mini.ts = htons(0xffff & fr->ts); 03637 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 03638 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 03639 } else { 03640 met = (struct ast_iax2_meta_trunk_entry *)ptr; 03641 /* Store call number and length in meta header */ 03642 met->callno = htons(pvt->callno); 03643 met->len = htons(f->datalen); 03644 /* Advance pointers/decrease length past trunk entry header */ 03645 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 03646 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 03647 } 03648 /* Copy actual trunk data */ 03649 memcpy(ptr, f->data, f->datalen); 03650 tpeer->trunkdatalen += f->datalen; 03651 03652 tpeer->calls++; 03653 ast_mutex_unlock(&tpeer->lock); 03654 } 03655 return 0; 03656 }
| static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 5887 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, iaxs, and send_command_immediate().
Referenced by socket_process().
05888 { 05889 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 05890 }
| static int iax2_write | ( | struct ast_channel * | c, | |
| struct ast_frame * | f | |||
| ) | [static] |
Definition at line 4529 of file chan_iax2.c.
References AST_FRAME_NULL, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, error(), f, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, iaxsl, PTR_TO_CALLNO, and ast_channel::tech_pvt.
04530 { 04531 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04532 int res = -1; 04533 ast_mutex_lock(&iaxsl[callno]); 04534 if (iaxs[callno]) { 04535 /* If there's an outstanding error, return failure now */ 04536 if (!iaxs[callno]->error) { 04537 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 04538 res = 0; 04539 /* Don't waste bandwidth sending null frames */ 04540 else if (f->frametype == AST_FRAME_NULL) 04541 res = 0; 04542 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 04543 res = 0; 04544 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 04545 res = 0; 04546 else 04547 /* Simple, just queue for transmission */ 04548 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 04549 } else { 04550 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); 04551 } 04552 } 04553 /* If it's already gone, just return */ 04554 ast_mutex_unlock(&iaxsl[callno]); 04555 return res; 04556 }
| static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 1484 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().
01485 { 01486 int res = 0; 01487 struct iax_firmware *cur; 01488 if (!ast_strlen_zero(dev)) { 01489 ast_mutex_lock(&waresl.lock); 01490 cur = waresl.wares; 01491 while(cur) { 01492 if (!strcmp(dev, (char *)cur->fwh->devname)) { 01493 res = ntohs(cur->fwh->version); 01494 break; 01495 } 01496 cur = cur->next; 01497 } 01498 ast_mutex_unlock(&waresl.lock); 01499 } 01500 return res; 01501 }
| static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 719 of file chan_iax2.c.
References ast_verbose().
Referenced by load_module().
00720 { 00721 if (iaxdebug) 00722 ast_verbose("%s", data); 00723 }
| static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 725 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
00726 { 00727 ast_log(LOG_WARNING, "%s", data); 00728 }
| static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
| const unsigned char * | dev, | |||
| unsigned int | desc | |||
| ) | [static] |
Definition at line 1503 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().
01504 { 01505 int res = -1; 01506 unsigned int bs = desc & 0xff; 01507 unsigned int start = (desc >> 8) & 0xffffff; 01508 unsigned int bytes; 01509 struct iax_firmware *cur; 01510 if (!ast_strlen_zero((char *)dev) && bs) { 01511 start *= bs; 01512 ast_mutex_lock(&waresl.lock); 01513 cur = waresl.wares; 01514 while(cur) { 01515 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) { 01516 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 01517 if (start < ntohl(cur->fwh->datalen)) { 01518 bytes = ntohl(cur->fwh->datalen) - start; 01519 if (bytes > bs) 01520 bytes = bs; 01521 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 01522 } else { 01523 bytes = 0; 01524 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 01525 } 01526 if (bytes == bs) 01527 res = 0; 01528 else 01529 res = 1; 01530 break; 01531 } 01532 cur = cur->next; 01533 } 01534 ast_mutex_unlock(&waresl.lock); 01535 } 01536 return res; 01537 }
| static int iax_park | ( | struct ast_channel * | chan1, | |
| struct ast_channel * | chan2 | |||
| ) | [static] |
Definition at line 6149 of file chan_iax2.c.
References ast_channel::amaflags, ast_calloc, ast_channel_alloc(), ast_channel_masquerade(), ast_do_masquerade(), ast_hangup(), ast_log(), ast_pthread_create_background, AST_STATE_DOWN, ast_channel::context, ast_channel::exten, free, iax_park_thread(), LOG_WARNING, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat.
Referenced by socket_process().
06150 { 06151 struct iax_dual *d; 06152 struct ast_channel *chan1m, *chan2m; 06153 pthread_t th; 06154 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 06155 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name); 06156 if (chan2m && chan1m) { 06157 /* Make formats okay */ 06158 chan1m->readformat = chan1->readformat; 06159 chan1m->writeformat = chan1->writeformat; 06160 ast_channel_masquerade(chan1m, chan1); 06161 /* Setup the extensions and such */ 06162 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 06163 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 06164 chan1m->priority = chan1->priority; 06165 06166 /* We make a clone of the peer channel too, so we can play 06167 back the announcement */ 06168 /* Make formats okay */ 06169 chan2m->readformat = chan2->readformat; 06170 chan2m->writeformat = chan2->writeformat; 06171 ast_channel_masquerade(chan2m, chan2); 06172 /* Setup the extensions and such */ 06173 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 06174 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 06175 chan2m->priority = chan2->priority; 06176 if (ast_do_masquerade(chan2m)) { 06177 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 06178 ast_hangup(chan2m); 06179 return -1; 06180 } 06181 } else { 06182 if (chan1m) 06183 ast_hangup(chan1m); 06184 if (chan2m) 06185 ast_hangup(chan2m); 06186 return -1; 06187 } 06188 if ((d = ast_calloc(1, sizeof(*d)))) { 06189 pthread_attr_t attr; 06190 06191 pthread_attr_init(&attr); 06192 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06193 06194 d->chan1 = chan1m; 06195 d->chan2 = chan2m; 06196 if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) { 06197 pthread_attr_destroy(&attr); 06198 return 0; 06199 } 06200 pthread_attr_destroy(&attr); 06201 free(d); 06202 } 06203 return -1; 06204 }
| static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 6129 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().
06130 { 06131 struct ast_channel *chan1, *chan2; 06132 struct iax_dual *d; 06133 struct ast_frame *f; 06134 int ext; 06135 int res; 06136 d = stuff; 06137 chan1 = d->chan1; 06138 chan2 = d->chan2; 06139 free(d); 06140 f = ast_read(chan1); 06141 if (f) 06142 ast_frfree(f); 06143 res = ast_park_call(chan1, chan2, 0, &ext); 06144 ast_hangup(chan2); 06145 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 06146 return NULL; 06147 }
Definition at line 1090 of file chan_iax2.c.
References iax_frame::af, iax_frame::cacheable, ast_frame::datalen, DIRECTION_INGRESS, iax_frame_new(), iax_frame_wrap(), and iax_frame::mallocd_datalen.
Referenced by socket_process().
01091 { 01092 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01093 if (new) { 01094 size_t mallocd_datalen = new->mallocd_datalen; 01095 memcpy(new, fr, sizeof(*new)); 01096 iax_frame_wrap(new, &fr->af); 01097 new->mallocd_datalen = mallocd_datalen; 01098 new->data = NULL; 01099 new->datalen = 0; 01100 new->direction = DIRECTION_INGRESS; 01101 new->retrans = -1; 01102 } 01103 return new; 01104 }
| static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 829 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, IAX_TYPE_DYNAMIC, and thread.
Referenced by iax2_process_thread(), and socket_read().
00830 { 00831 if (thread->type == IAX_TYPE_DYNAMIC) { 00832 AST_LIST_LOCK(&dynamic_list); 00833 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 00834 AST_LIST_UNLOCK(&dynamic_list); 00835 } else { 00836 AST_LIST_LOCK(&idle_list); 00837 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 00838 AST_LIST_UNLOCK(&idle_list); 00839 } 00840 00841 return; 00842 }
| static void jb_debug_output | ( | const char * | fmt, | |
| ... | ||||
| ) | [static] |
Definition at line 754 of file chan_iax2.c.
References ast_verbose().
Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug().
00755 { 00756 va_list args; 00757 char buf[1024]; 00758 00759 va_start(args, fmt); 00760 vsnprintf(buf, 1024, fmt, args); 00761 va_end(args); 00762 00763 ast_verbose(buf); 00764 }
| static void jb_error_output | ( | const char * | fmt, | |
| ... | ||||
| ) | [static] |
Definition at line 730 of file chan_iax2.c.
References ast_log(), and LOG_ERROR.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00731 { 00732 va_list args; 00733 char buf[1024]; 00734 00735 va_start(args, fmt); 00736 vsnprintf(buf, 1024, fmt, args); 00737 va_end(args); 00738 00739 ast_log(LOG_ERROR, buf); 00740 }
| static void jb_warning_output | ( | const char * | fmt, | |
| ... | ||||
| ) | [static] |
Definition at line 742 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00743 { 00744 va_list args; 00745 char buf[1024]; 00746 00747 va_start(args, fmt); 00748 vsnprintf(buf, 1024, fmt, args); 00749 va_end(args); 00750 00751 ast_log(LOG_WARNING, buf); 00752 }
| static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 10138 of file chan_iax2.c.
References __unload_module(), 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_mutex_init(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_register_application(), ast_register_switch(), ast_verbose(), cli_iax2, config, iax2_do_register(), iax2_poke_peer(), iax2_prov_app(), iax2_switch, iax2_tech, iax_debug_output(), iax_error_output(), iax_provision_reload(), iax_set_error(), iax_set_output(), iaxpeer_function, iaxq, iaxs, iaxsl, iaxvar_function, io, io_context_create(), jb_error_output(), jb_setoutput(), jb_warning_output(), ast_firmware_list::lock, LOG_ERROR, LOG_WARNING, manager_iax2_show_netstats(), manager_iax2_show_peers(), netsock, option_verbose, outsock, reload_firmware(), sched, sched_context_create(), set_config(), iax2_peer::sockfd, start_network_thread(), VERBOSE_PREFIX_2, and waresl.
10139 { 10140 char *config = "iax.conf"; 10141 int res = 0; 10142 int x; 10143 struct iax2_registry *reg = NULL; 10144 struct iax2_peer *peer = NULL; 10145 10146 ast_custom_function_register(&iaxpeer_function); 10147 ast_custom_function_register(&iaxvar_function); 10148 10149 iax_set_output(iax_debug_output); 10150 iax_set_error(iax_error_output); 10151 jb_setoutput(jb_error_output, jb_warning_output, NULL); 10152 10153 #ifdef HAVE_ZAPTEL 10154 #ifdef ZT_TIMERACK 10155 timingfd = open("/dev/zap/timer", O_RDWR); 10156 if (timingfd < 0) 10157 #endif 10158 timingfd = open("/dev/zap/pseudo", O_RDWR); 10159 if (timingfd < 0) 10160 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno)); 10161 #endif 10162 10163 memset(iaxs, 0, sizeof(iaxs)); 10164 10165 for (x=0;x<IAX_MAX_CALLS;x++) 10166 ast_mutex_init(&iaxsl[x]); 10167 10168 ast_cond_init(&sched_cond, NULL); 10169 10170 io = io_context_create(); 10171 sched = sched_context_create(); 10172 10173 if (!io || !sched) { 10174 ast_log(LOG_ERROR, "Out of memory\n"); 10175 return -1; 10176 } 10177 10178 netsock = ast_netsock_list_alloc(); 10179 if (!netsock) { 10180 ast_log(LOG_ERROR, "Could not allocate netsock list.\n"); 10181 return -1; 10182 } 10183 ast_netsock_init(netsock); 10184 10185 outsock = ast_netsock_list_alloc(); 10186 if (!outsock) { 10187 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 10188 return -1; 10189 } 10190 ast_netsock_init(outsock); 10191 10192 ast_mutex_init(&waresl.lock); 10193 10194 AST_LIST_HEAD_INIT(&iaxq.queue); 10195 10196 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 10197 10198 ast_register_application(papp, iax2_prov_app, psyn, pdescrip); 10199 10200 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" ); 10201 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" ); 10202 10203 if(set_config(config, 0) == -1) 10204 return AST_MODULE_LOAD_DECLINE; 10205 10206 if (ast_channel_register(&iax2_tech)) { 10207 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 10208 __unload_module(); 10209 return -1; 10210 } 10211 10212 if (ast_register_switch(&iax2_switch)) 10213 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 10214 10215 res = start_network_thread(); 10216 if (!res) { 10217 if (option_verbose > 1) 10218 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n"); 10219 } else { 10220 ast_log(LOG_ERROR, "Unable to start network thread\n"); 10221 ast_netsock_release(netsock); 10222 ast_netsock_release(outsock); 10223 } 10224 10225 AST_LIST_LOCK(®istrations); 10226 AST_LIST_TRAVERSE(®istrations, reg, entry) 10227 iax2_do_register(reg); 10228 AST_LIST_UNLOCK(®istrations); 10229 10230 AST_LIST_LOCK(&peers); 10231 AST_LIST_TRAVERSE(&peers, peer, entry) { 10232 if (peer->sockfd < 0) 10233 peer->sockfd = defaultsockfd; 10234 iax2_poke_peer(peer, 0); 10235 } 10236 AST_LIST_UNLOCK(&peers); 10237 reload_firmware(); 10238 iax_provision_reload(); 10239 return res; 10240 }
| static void lock_both | ( | unsigned short | callno0, | |
| unsigned short | callno1 | |||
| ) | [static] |
Definition at line 3058 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
03059 { 03060 ast_mutex_lock(&iaxsl[callno0]); 03061 while (ast_mutex_trylock(&iaxsl[callno1])) { 03062 ast_mutex_unlock(&iaxsl[callno0]); 03063 usleep(10); 03064 ast_mutex_lock(&iaxsl[callno0]); 03065 } 03066 }
| static int make_trunk | ( | unsigned short | callno, | |
| int | locked | |||
| ) | [static] |
Definition at line 1158 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), chan_iax2_pvt::callno, iaxs, iaxsl, chan_iax2_pvt::lagid, LOG_WARNING, MIN_REUSE_TIME, chan_iax2_pvt::pingid, sched, send_lagrq(), send_ping(), and TRUNK_CALL_START.
Referenced by iax2_request(), and socket_process().
01159 { 01160 int x; 01161 int res= 0; 01162 struct timeval now; 01163 if (iaxs[callno]->oseqno) { 01164 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 01165 return -1; 01166 } 01167 if (callno & TRUNK_CALL_START) { 01168 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01169 return -1; 01170 } 01171 gettimeofday(&now, NULL); 01172 for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) { 01173 ast_mutex_lock(&iaxsl[x]); 01174 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01175 iaxs[x] = iaxs[callno]; 01176 iaxs[x]->callno = x; 01177 iaxs[callno] = NULL; 01178 /* Update the two timers that should have been started */ 01179 if (iaxs[x]->pingid > -1) 01180 ast_sched_del(sched, iaxs[x]->pingid); 01181 if (iaxs[x]->lagid > -1) 01182 ast_sched_del(sched, iaxs[x]->lagid); 01183 iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01184 iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01185 if (locked) 01186 ast_mutex_unlock(&iaxsl[callno]); 01187 res = x; 01188 if (!locked) 01189 ast_mutex_unlock(&iaxsl[x]); 01190 break; 01191 } 01192 ast_mutex_unlock(&iaxsl[x]); 01193 } 01194 if (x >= IAX_MAX_CALLS - 1) { 01195 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01196 return -1; 01197 } 01198 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x); 01199 /* We move this call from a non-trunked to a trunked call */ 01200 update_max_trunk(); 01201 update_max_nontrunk(); 01202 return res; 01203 }
| static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 4243 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), RESULT_SUCCESS, and s.
Referenced by load_module().
04244 { 04245 ast_cli_netstats(s, -1, 0); 04246 astman_append(s, "\r\n"); 04247 return RESULT_SUCCESS; 04248 }
| static int manager_iax2_show_peers | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 4276 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), and s.
Referenced by load_module().
04277 { 04278 char *a[] = { "iax2", "show", "users" }; 04279 int ret; 04280 const char *id = astman_get_header(m,"ActionID"); 04281 04282 if (!ast_strlen_zero(id)) 04283 astman_append(s, "ActionID: %s\r\n",id); 04284 ret = __iax2_show_peers(1, -1, s, 3, a ); 04285 astman_append(s, "\r\n\r\n" ); 04286 return ret; 04287 } /* /JDG */
| static int match | ( | struct sockaddr_in * | sin, | |
| unsigned short | callno, | |||
| unsigned short | dcallno, | |||
| struct chan_iax2_pvt * | cur | |||
| ) | [static] |
Definition at line 1110 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::callno, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, and chan_iax2_pvt::transferring.
Referenced by ast_parse_device_state(), find_callno(), find_command(), get_sip_pvt_byid_locked(), handle_updates(), pbx_find_extension(), realtime_switch_common(), and softhangup_exec().
01111 { 01112 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01113 (cur->addr.sin_port == sin->sin_port)) { 01114 /* This is the main host */ 01115 if ((cur->peercallno == callno) || 01116 ((dcallno == cur->callno) && !cur->peercallno)) { 01117 /* That's us. Be sure we keep track of the peer call number */ 01118 return 1; 01119 } 01120 } 01121 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01122 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01123 /* We're transferring */ 01124 if (dcallno == cur->callno) 01125 return 1; 01126 } 01127 return 0; 01128 }
| static void memcpy_decrypt | ( | unsigned char * | dst, | |
| const unsigned char * | src, | |||
| int | len, | |||
| aes_decrypt_ctx * | dcx | |||
| ) | [static] |
Definition at line 3664 of file chan_iax2.c.
References aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
03665 { 03666 #if 0 03667 /* Debug with "fake encryption" */ 03668 int x; 03669 if (len % 16) 03670 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 03671 for (x=0;x<len;x++) 03672 dst[x] = src[x] ^ 0xff; 03673 #else 03674 unsigned char lastblock[16] = { 0 }; 03675 int x; 03676 while(len > 0) { 03677 aes_decrypt(src, dst, dcx); 03678 for (x=0;x<16;x++) 03679 dst[x] ^= lastblock[x]; 03680 memcpy(lastblock, src, sizeof(lastblock)); 03681 dst += 16; 03682 src += 16; 03683 len -= 16; 03684 } 03685 #endif 03686 }
| static void memcpy_encrypt | ( | unsigned char * | dst, | |
| const unsigned char * | src, | |||
| int | len, | |||
| aes_encrypt_ctx * | ecx | |||
| ) | [static] |
Definition at line 3688 of file chan_iax2.c.
References aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
03689 { 03690 #if 0 03691 /* Debug with "fake encryption" */ 03692 int x; 03693 if (len % 16) 03694 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 03695 for (x=0;x<len;x++) 03696 dst[x] = src[x] ^ 0xff; 03697 #else 03698 unsigned char curblock[16] = { 0 }; 03699 int x; 03700 while(len > 0) { 03701 for (x=0;x<16;x++) 03702 curblock[x] ^= src[x]; 03703 aes_encrypt(curblock, dst, ecx); 03704 memcpy(curblock, dst, sizeof(curblock)); 03705 dst += 16; 03706 src += 16; 03707 len -= 16; 03708 } 03709 #endif 03710 }
| static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
| unsigned int | enc | |||
| ) | [static] |
Definition at line 4834 of file chan_iax2.c.
References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.
Referenced by authenticate_reply(), and socket_process().
04835 { 04836 /* Select exactly one common encryption if there are any */ 04837 p->encmethods &= enc; 04838 if (p->encmethods) { 04839 if (p->encmethods & IAX_ENCRYPT_AES128) 04840 p->encmethods = IAX_ENCRYPT_AES128; 04841 else 04842 p->encmethods = 0; 04843 } 04844 }
| static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 8148 of file chan_iax2.c.
References ast_io_add(), AST_IO_IN, AST_IO_PRI, ast_io_wait(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_sched_add(), attempt_transmit(), f, iax_frame_free(), iaxq, iaxs, iaxsl, io, sched, send_packet(), signal_condition(), and timing_read().
Referenced by start_network_thread().
08149 { 08150 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 08151 from the network, and queue them for delivery to the channels */ 08152 int res, count, wakeup; 08153 struct iax_frame *f; 08154 08155 if (timingfd > -1) 08156 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL); 08157 08158 for(;;) { 08159 pthread_testcancel(); 08160 08161 /* Go through the queue, sending messages which have not yet been 08162 sent, and scheduling retransmissions if appropriate */ 08163 AST_LIST_LOCK(&iaxq.queue); 08164 count = 0; 08165 wakeup = -1; 08166 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) { 08167 if (f->sentyet) 08168 continue; 08169 08170 /* Try to lock the pvt, if we can't... don't fret - defer it till later */ 08171 if (ast_mutex_trylock(&iaxsl[f->callno])) { 08172 wakeup = 1; 08173 continue; 08174 } 08175 08176 f->sentyet++; 08177 08178 if (iaxs[f->callno]) { 08179 send_packet(f); 08180 count++; 08181 } 08182 08183 ast_mutex_unlock(&iaxsl[f->callno]); 08184 08185 if (f->retries < 0) { 08186 /* This is not supposed to be retransmitted */ 08187 AST_LIST_REMOVE(&iaxq.queue, f, list); 08188 iaxq.count--; 08189 /* Free the iax frame */ 08190 iax_frame_free(f); 08191 } else { 08192 /* We need reliable delivery. Schedule a retransmission */ 08193 f->retries++; 08194 f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f); 08195 signal_condition(&sched_lock, &sched_cond); 08196 } 08197 } 08198 AST_LIST_TRAVERSE_SAFE_END 08199 AST_LIST_UNLOCK(&iaxq.queue); 08200 08201 pthread_testcancel(); 08202 08203 if (count >= 20) 08204 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 08205 08206 /* Now do the IO, and run scheduled tasks */ 08207 res = ast_io_wait(io, wakeup); 08208 if (res >= 0) { 08209 if (res >= 20) 08210 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 08211 } 08212 } 08213 return NULL; 08214 }
| static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
| int | lockpeer, | |||
| const char * | host | |||
| ) | [static] |
Definition at line 1052 of file chan_iax2.c.
References ast_calloc, ast_string_field_init, ast_string_field_set, exten, free, jb_new(), jb_setconf(), jb_conf::max_contig_interp, jb_conf::max_jitterbuf, iax2_user::prefs, and jb_conf::resync_threshold.
Referenced by find_callno().
01053 { 01054 struct chan_iax2_pvt *tmp; 01055 jb_conf jbconf; 01056 01057 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) 01058 return NULL; 01059 01060 if (ast_string_field_init(tmp, 32)) { 01061 free(tmp); 01062 tmp = NULL; 01063 return NULL; 01064 } 01065 01066 tmp->prefs = prefs; 01067 tmp->callno = 0; 01068 tmp->peercallno = 0; 01069 tmp->transfercallno = 0; 01070 tmp->bridgecallno = 0; 01071 tmp->pingid = -1; 01072 tmp->lagid = -1; 01073 tmp->autoid = -1; 01074 tmp->authid = -1; 01075 tmp->initid = -1; 01076 01077 ast_string_field_set(tmp,exten, "s"); 01078 ast_string_field_set(tmp,host, host); 01079 01080 tmp->jb = jb_new(); 01081 tmp->jbid = -1; 01082 jbconf.max_jitterbuf = maxjitterbuffer; 01083 jbconf.resync_threshold = resyncthreshold; 01084 jbconf.max_contig_interp = maxjitterinterps; 01085 jb_setconf(tmp->jb,&jbconf); 01086 01087 return tmp; 01088 }
| 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 2780 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().
02781 { 02782 if (ast_strlen_zero(data)) 02783 return; 02784 02785 pds->peer = strsep(&data, "/"); 02786 pds->exten = strsep(&data, "/"); 02787 pds->options = data; 02788 02789 if (pds->exten) { 02790 data = pds->exten; 02791 pds->exten = strsep(&data, "@"); 02792 pds->context = data; 02793 } 02794 02795 if (strchr(pds->peer, '@')) { 02796 data = pds->peer; 02797 pds->username = strsep(&data, "@"); 02798 pds->peer = data; 02799 } 02800 02801 if (pds->username) { 02802 data = pds->username; 02803 pds->username = strsep(&data, ":"); 02804 pds->password = data; 02805 } 02806 02807 data = pds->peer; 02808 pds->peer = strsep(&data, ":"); 02809 pds->port = data; 02810 02811 /* check for a key name wrapped in [] in the secret position, if found, 02812 move it to the key field instead 02813 */ 02814 if (pds->password && (pds->password[0] == '[')) { 02815 pds->key = ast_strip_quoted(pds->password, "[", "]"); 02816 pds->password = NULL; 02817 } 02818 }
| 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 8298 of file chan_iax2.c.
References ast_get_ip(), ast_log(), ast_netsock_bind(), ast_netsock_find(), ast_netsock_sockfd(), ast_netsock_unref(), ast_strdupa, check_srcaddr(), IAX_DEFAULT_PORTNO, io, LOG_WARNING, netsock, outsock, socket_read(), iax2_peer::sockfd, and strsep().
Referenced by build_peer().
08299 { 08300 struct sockaddr_in sin; 08301 int nonlocal = 1; 08302 int port = IAX_DEFAULT_PORTNO; 08303 int sockfd = defaultsockfd; 08304 char *tmp; 08305 char *addr; 08306 char *portstr; 08307 08308 if (!(tmp = ast_strdupa(srcaddr))) 08309 return -1; 08310 08311 addr = strsep(&tmp, ":"); 08312 portstr = tmp; 08313 08314 if (portstr) { 08315 port = atoi(portstr); 08316 if (port < 1) 08317 port = IAX_DEFAULT_PORTNO; 08318 } 08319 08320 if (!ast_get_ip(&sin, addr)) { 08321 struct ast_netsock *sock; 08322 int res; 08323 08324 sin.sin_port = 0; 08325 sin.sin_family = AF_INET; 08326 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 08327 if (res == 0) { 08328 /* ip address valid. */ 08329 sin.sin_port = htons(port); 08330 if (!(sock = ast_netsock_find(netsock, &sin))) 08331 sock = ast_netsock_find(outsock, &sin); 08332 if (sock) { 08333 sockfd = ast_netsock_sockfd(sock); 08334 nonlocal = 0; 08335 } else { 08336 unsigned int orig_saddr = sin.sin_addr.s_addr; 08337 /* INADDR_ANY matches anyway! */ 08338 sin.sin_addr.s_addr = INADDR_ANY; 08339 if (ast_netsock_find(netsock, &sin)) { 08340 sin.sin_addr.s_addr = orig_saddr; 08341 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL); 08342 if (sock) { 08343 sockfd = ast_netsock_sockfd(sock); 08344 ast_netsock_unref(sock); 08345 nonlocal = 0; 08346 } else { 08347 nonlocal = 2; 08348 } 08349 } 08350 } 08351 } 08352 } 08353 08354 peer->sockfd = sockfd; 08355 08356 if (nonlocal == 1) { 08357 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 08358 srcaddr, peer->name); 08359 return -1; 08360 } else if (nonlocal == 2) { 08361 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 08362 srcaddr, peer->name); 08363 return -1; 08364 } else { 08365 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 08366 return 0; 08367 } 08368 }
| static int peer_status | ( | struct iax2_peer * | peer, | |
| char * | status, | |||
| int | statuslen | |||
| ) | [static] |
peer_status: Report Peer status in character string
Definition at line 1995 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().
01996 { 01997 int res = 0; 01998 if (peer->maxms) { 01999 if (peer->lastms < 0) { 02000 ast_copy_string(status, "UNREACHABLE", statuslen); 02001 } else if (peer->lastms > peer->maxms) { 02002 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 02003 res = 1; 02004 } else if (peer->lastms) { 02005 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 02006 res = 1; 02007 } else { 02008 ast_copy_string(status, "UNKNOWN", statuslen); 02009 } 02010 } else { 02011 ast_copy_string(status, "Unmonitored", statuslen); 02012 res = -1; 02013 } 02014 return res; 02015 }
| static void prune_peers | ( | void | ) | [static] |
Definition at line 8921 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_test_flag, destroy_peer(), and IAX_DELME.
08921 { 08922 /* Prune peers who still are supposed to be deleted */ 08923 struct iax2_peer *peer = NULL; 08924 08925 AST_LIST_LOCK(&peers); 08926 AST_LIST_TRAVERSE_SAFE_BEGIN(&peers, peer, entry) { 08927 if (ast_test_flag(peer, IAX_DELME)) { 08928 destroy_peer(peer); 08929 AST_LIST_REMOVE_CURRENT(&peers, entry); 08930 } 08931 } 08932 AST_LIST_TRAVERSE_SAFE_END 08933 AST_LIST_UNLOCK(&peers); 08934 }
| static void prune_users | ( | void | ) | [static] |
Definition at line 8880 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_test_flag, destroy_user(), and IAX_DELME.
Referenced by reload_config().
08881 { 08882 struct iax2_user *user = NULL; 08883 08884 AST_LIST_LOCK(&users); 08885 AST_LIST_TRAVERSE_SAFE_BEGIN(&users, user, entry) { 08886 if (ast_test_flag(user, IAX_DELME)) { 08887 destroy_user(user); 08888 AST_LIST_REMOVE_CURRENT(&users, entry); 08889 } 08890 } 08891 AST_LIST_TRAVERSE_SAFE_END 08892 AST_LIST_UNLOCK(&users); 08893 08894 }
| static int raw_hangup | ( | struct sockaddr_in * | sin, | |
| unsigned short | src, | |||
| unsigned short | dst, | |||
| int | sockfd | |||
| ) | [static] |
Definition at line 4814 of file chan_iax2.c.
References AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), compress_subclass(), ast_iax2_full_hdr::csub, ast_iax2_full_hdr::dcallno, IAX_COMMAND_INVAL, IAX_FLAG_FULL, iax_showframe(), ast_iax2_full_hdr::iseqno, option_debug, ast_iax2_full_hdr::oseqno, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::ts, and ast_iax2_full_hdr::type.
Referenced by socket_process().
04815 { 04816 struct ast_iax2_full_hdr fh; 04817 fh.scallno = htons(src | IAX_FLAG_FULL); 04818 fh.dcallno = htons(dst); 04819 fh.ts = 0; 04820 fh.oseqno = 0; 04821 fh.iseqno = 0; 04822 fh.type = AST_FRAME_IAX; 04823 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 04824 if (iaxdebug) 04825 iax_showframe(NULL, &fh, 0, sin, 0); 04826 #if 0 04827 if (option_debug) 04828 #endif 04829 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n", 04830 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 04831 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 04832 }
| static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
| struct sockaddr_in * | sin | |||
| ) | [static] |
Definition at line 2456 of file chan_iax2.c.
References ast_inet_ntoa(), ast_load_realtime(), ast_test_flag, ast_variables_destroy(), build_peer(), destroy_peer(), globalflags, IAX_RTCACHEFRIENDS, ast_variable::name, ast_variable::next, ast_variable::value, and var.
02457 { 02458 struct ast_variable *var; 02459 struct ast_variable *tmp; 02460 struct iax2_peer *peer=NULL; 02461 time_t regseconds = 0, nowtime; 02462 int dynamic=0; 02463 02464 if (peername) 02465 var = ast_load_realtime("iaxpeers", "name", peername, NULL); 02466 else { 02467 char porta[25]; 02468 sprintf(porta, "%d", ntohs(sin->sin_port)); 02469 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02470 if (var) { 02471 /* We'll need the peer name in order to build the structure! */ 02472 for (tmp = var; tmp; tmp = tmp->next) { 02473 if (!strcasecmp(tmp->name, "name")) 02474 peername = tmp->value; 02475 } 02476 } 02477 } 02478 if (!var) 02479 return NULL; 02480 02481 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 02482 02483 if (!peer) { 02484 ast_variables_destroy(var); 02485 return NULL; 02486 } 02487 02488 for (tmp = var; tmp; tmp = tmp->next) { 02489 /* Make sure it's not a user only... */ 02490 if (!strcasecmp(tmp->name, "type")) { 02491 if (strcasecmp(tmp->value, "friend") && 02492 strcasecmp(tmp->value, "peer")) { 02493 /* Whoops, we weren't supposed to exist! */ 02494 destroy_peer(peer); 02495 peer = NULL; 02496 break; 02497 } 02498 } else if (!strcasecmp(tmp->name, "regseconds")) { 02499 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 02500 } else if (!strcasecmp(tmp->name, "ipaddr")) { 02501 inet_aton(tmp->value, &(peer->addr.sin_addr)); 02502 } else if (!strcasecmp(tmp->name, "port")) { 02503 peer->addr.sin_port = htons(atoi(tmp->value)); 02504 } else if (!strcasecmp(tmp->name, "host")) { 02505 if (!strcasecmp(tmp->value, "dynamic")) 02506 dynamic = 1; 02507 } 02508 } 02509 02510 ast_variables_destroy(var); 02511 02512 if (!peer) 02513 return NULL; 02514 02515 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02516 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 02517 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 02518 if (peer->expire > -1) 02519 ast_sched_del(sched, peer->expire); 02520 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, (void*)peer->name); 02521 } 02522 AST_LIST_LOCK(&peers); 02523 AST_LIST_INSERT_HEAD(&peers, peer, entry); 02524 AST_LIST_UNLOCK(&peers); 02525 if (ast_test_flag(peer, IAX_DYNAMIC)) 02526 reg_source_db(peer); 02527 } else { 02528 ast_set_flag(peer, IAX_TEMPONLY); 02529 } 02530 02531 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 02532 time(&nowtime); 02533 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 02534 memset(&peer->addr, 0, sizeof(peer->addr)); 02535 realtime_update_peer(peer->name, &peer->addr, 0); 02536 if (option_debug) 02537 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 02538 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02539 } 02540 else { 02541 if (option_debug) 02542 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 02543 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 02544 } 02545 } 02546 02547 return peer; 02548 }
| static void realtime_update_peer | ( | const char * | peername, | |
| struct sockaddr_in * | sin, | |||
| time_t | regtime | |||
| ) | [static] |
Definition at line 2591 of file chan_iax2.c.
References ast_inet_ntoa(), and ast_update_realtime().
Referenced by __expire_registry(), update_peer(), and update_registry().
02592 { 02593 char port[10]; 02594 char regseconds[20]; 02595 02596 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 02597 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02598 ast_update_realtime("iaxpeers", "name", peername, 02599 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 02600 "regseconds", regseconds, NULL); 02601 }
| static struct iax2_user* realtime_user | ( | const char * | username | ) | [static] |
Definition at line 2550 of file chan_iax2.c.
References AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), build_user(), globalflags, IAX_RTCACHEFRIENDS, IAX_TEMPONLY, ast_variable::name, ast_variable::next, ast_variable::value, and var.
02551 { 02552 struct ast_variable *var; 02553 struct ast_variable *tmp; 02554 struct iax2_user *user=NULL; 02555 02556 var = ast_load_realtime("iaxusers", "name", username, NULL); 02557 if (!var) 02558 return NULL; 02559 02560 tmp = var; 02561 while(tmp) { 02562 /* Make sure it's not a peer only... */ 02563 if (!strcasecmp(tmp->name, "type")) { 02564 if (strcasecmp(tmp->value, "friend") && 02565 strcasecmp(tmp->value, "user")) { 02566 return NULL; 02567 } 02568 } 02569 tmp = tmp->next; 02570 } 02571 02572 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 02573 02574 ast_variables_destroy(var); 02575 02576 if (!user) 02577 return NULL; 02578 02579 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 02580 ast_set_flag(user, IAX_RTCACHEFRIENDS); 02581 AST_LIST_LOCK(&users); 02582 AST_LIST_INSERT_HEAD(&users, user, entry); 02583 AST_LIST_UNLOCK(&users); 02584 } else { 02585 ast_set_flag(user, IAX_TEMPONLY); 02586 } 02587 02588 return user; 02589 }
| static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 5569 of file chan_iax2.c.
References iax2_peer::addr, ast_db_get(), ast_device_state_changed(), ast_inet_ntoa(), ast_sched_add(), ast_sched_del(), ast_test_flag, ast_verbose(), iax2_peer::expire, expire_registry(), iax2_peer::expiry, iax2_poke_peer(), iax2_regfunk, IAX_TEMPONLY, option_verbose, register_peer_exten(), sched, and VERBOSE_PREFIX_3.
Referenced by build_peer(), set_config(), and temp_peer().
05570 { 05571 char data[80]; 05572 struct in_addr in; 05573 char *c, *d; 05574 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 05575 c = strchr(data, ':'); 05576 if (c) { 05577 *c = '\0'; 05578 c++; 05579 if (inet_aton(data, &in)) { 05580 d = strchr(c, ':'); 05581 if (d) { 05582 *d = '\0'; 05583 d++; 05584 if (option_verbose > 2) 05585 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 05586 ast_inet_ntoa(in), atoi(c), atoi(d)); 05587 iax2_poke_peer(p, 0); 05588 p->expiry = atoi(d); 05589 memset(&p->addr, 0, sizeof(p->addr)); 05590 p->addr.sin_family = AF_INET; 05591 p->addr.sin_addr = in; 05592 p->addr.sin_port = htons(atoi(c)); 05593 if (p->expire > -1) 05594 ast_sched_del(sched, p->expire); 05595 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05596 p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p->name); 05597 if (iax2_regfunk) 05598 iax2_regfunk(p->name, 1); 05599 register_peer_exten(p, 1); 05600 } 05601 05602 } 05603 } 05604 } 05605 }
| static void register_peer_exten | ( | struct iax2_peer * | peer, | |
| int | onoff | |||
| ) | [static] |
Definition at line 5498 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(), destroy_peer(), expire_register(), parse_register_contact(), reg_source_db(), sip_destroy_peer(), and update_registry().
05499 { 05500 char multi[256]; 05501 char *stringp, *ext; 05502 if (!ast_strlen_zero(regcontext)) { 05503 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 05504 stringp = multi; 05505 while((ext = strsep(&stringp, "&"))) { 05506 if (onoff) { 05507 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 05508 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 05509 "Noop", ast_strdup(peer->name), ast_free, "IAX2"); 05510 } else 05511 ast_context_remove_extension(regcontext, ext, 1, NULL); 05512 } 05513 } 05514 }
| static int register_verify | ( | int | callno, | |
| struct sockaddr_in * | sin, | |||
| struct iax_ies * | ies | |||
| ) | [static] |
Verify inbound registration.
Definition at line 4975 of file chan_iax2.c.
References iax2_peer::addr, ast_apply_ha(), ast_check_signature, ast_clear_flag, ast_inet_ntoa(), ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_set_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, iax2_peer::authmethods, destroy_peer(), find_peer(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, IAX_STATE_UNCHANGED, IAX_TEMPONLY, iaxs, ies, inaddrcmp(), key(), LOG_NOTICE, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), and strsep().
Referenced by handle_request_register(), and socket_process().
04976 { 04977 char requeststr[256] = ""; 04978 char peer[256] = ""; 04979 char md5secret[256] = ""; 04980 char rsasecret[256] = ""; 04981 char secret[256] = ""; 04982 struct iax2_peer *p; 04983 struct ast_key *key; 04984 char *keyn; 04985 int x; 04986 int expire = 0; 04987 04988 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED); 04989 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 04990 if (ies->username) 04991 ast_copy_string(peer, ies->username, sizeof(peer)); 04992 if (ies->password) 04993 ast_copy_string(secret, ies->password, sizeof(secret)); 04994 if (ies->md5_result) 04995 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 04996 if (ies->rsa_result) 04997 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 04998 if (ies->refresh) 04999 expire = ies->refresh; 05000 05001 if (ast_strlen_zero(peer)) { 05002 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 05003 return -1; 05004 } 05005 05006 /* SLD: first call to lookup peer during registration */ 05007 p = find_peer(peer, 1); 05008 05009 if (!p) { 05010 if (authdebug) 05011 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05012 return -1; 05013 } 05014 05015 if (!ast_test_flag(p, IAX_DYNAMIC)) { 05016 if (authdebug) 05017 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05018 if (ast_test_flag(p, IAX_TEMPONLY)) 05019 destroy_peer(p); 05020 return -1; 05021 } 05022 05023 if (!ast_apply_ha(p->ha, sin)) { 05024 if (authdebug) 05025 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05026 if (ast_test_flag(p, IAX_TEMPONLY)) 05027 destroy_peer(p); 05028 return -1; 05029 } 05030 if (!inaddrcmp(&p->addr, sin)) 05031 ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED); 05032 ast_string_field_set(iaxs[callno], secret, p->secret); 05033 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 05034 /* Check secret against what we have on file */ 05035 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05036 if (!ast_strlen_zero(p->inkeys)) { 05037 char tmpkeys[256]; 05038 char *stringp=NULL; 05039 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 05040 stringp=tmpkeys; 05041 keyn = strsep(&stringp, ":"); 05042 while(keyn) { 05043 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05044 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 05045 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05046 break; 05047 } else if (!key) 05048 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 05049 keyn = strsep(&stringp, ":"); 05050 } 05051 if (!keyn) { 05052 if (authdebug) 05053 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 05054 if (ast_test_flag(p, IAX_TEMPONLY)) 05055 destroy_peer(p); 05056 return -1; 05057 } 05058 } else { 05059 if (authdebug) 05060 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 05061 if (ast_test_flag(p, IAX_TEMPONLY)) 05062 destroy_peer(p); 05063 return -1; 05064 } 05065 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05066 struct MD5Context md5; 05067 unsigned char digest[16]; 05068 char *tmppw, *stringp; 05069 05070 tmppw = ast_strdupa(p->secret); 05071 stringp = tmppw; 05072 while((tmppw = strsep(&stringp, ";"))) { 05073 MD5Init(&md5); 05074 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 05075 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05076 MD5Final(digest, &md5); 05077 for (x=0;x<16;x++) 05078 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05079 if (!strcasecmp(requeststr, md5secret)) 05080 break; 05081 } 05082 if (tmppw) { 05083 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05084 } else { 05085 if (authdebug) 05086 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 05087 if (ast_test_flag(p, IAX_TEMPONLY)) 05088 destroy_peer(p); 05089 return -1; 05090 } 05091 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 05092 /* They've provided a plain text password and we support that */ 05093 if (strcmp(secret, p->secret)) { 05094 if (authdebug) 05095 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05096 if (ast_test_flag(p, IAX_TEMPONLY)) 05097 destroy_peer(p); 05098 return -1; 05099 } else 05100 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05101 } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) { 05102 if (authdebug) 05103 ast_log(LOG_NOTICE, "Inappropriate authentication received\n"); 05104 if (ast_test_flag(p, IAX_TEMPONLY)) 05105 destroy_peer(p); 05106 return -1; 05107 } 05108 ast_string_field_set(iaxs[callno], peer, peer); 05109 /* Choose lowest expiry number */ 05110 if (expire && (expire < iaxs[callno]->expiry)) 05111 iaxs[callno]->expiry = expire; 05112 05113 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05114 05115 if (ast_test_flag(p, IAX_TEMPONLY)) 05116 destroy_peer(p); 05117 return 0; 05118 05119 }
| static int registry_authrequest | ( | const char * | name, | |
| int | callno | |||
| ) | [static] |
Definition at line 5714 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_random(), ast_string_field_set, ast_test_flag, iax2_peer::authmethods, destroy_peer(), find_peer(), IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_COMMAND_REGAUTH, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CHALLENGE, IAX_IE_USERNAME, IAX_TEMPONLY, iaxs, LOG_WARNING, and send_command().
Referenced by socket_process().
05715 { 05716 struct iax_ie_data ied; 05717 struct iax2_peer *p; 05718 char challenge[10]; 05719 /* SLD: third call to find_peer in registration */ 05720 p = find_peer(name, 1); 05721 if (p) { 05722 memset(&ied, 0, sizeof(ied)); 05723 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 05724 if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 05725 /* Build the challenge */ 05726 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 05727 ast_string_field_set(iaxs[callno], challenge, challenge); 05728 /* snprintf(iaxs[callno]->challenge, sizeof(iaxs[callno]->challenge), "%d", (int)ast_random()); */ 05729 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 05730 } 05731 iax_ie_append_str(&ied, IAX_IE_USERNAME, name); 05732 if (ast_test_flag(p, IAX_TEMPONLY)) 05733 destroy_peer(p); 05734 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);; 05735 } 05736 ast_log(LOG_WARNING, "No such peer '%s'\n", name); 05737 return 0; 05738 }
| static int registry_rerequest | ( | struct iax_ies * | ies, | |
| int | callno, | |||
| struct sockaddr_in * | sin | |||
| ) | [static] |
Definition at line 5740 of file chan_iax2.c.
References iax2_registry::addr, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_strlen_zero(), authenticate(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, ies, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_AUTHSENT, iax2_registry::regstate, iax2_registry::secret, send_command(), and iax2_registry::username.
Referenced by socket_process().
05741 { 05742 struct iax2_registry *reg; 05743 /* Start pessimistic */ 05744 struct iax_ie_data ied; 05745 char peer[256] = ""; 05746 char challenge[256] = ""; 05747 int res; 05748 int authmethods = 0; 05749 if (ies->authmethods) 05750 authmethods = ies->authmethods; 05751 if (ies->username) 05752 ast_copy_string(peer, ies->username, sizeof(peer)); 05753 if (ies->challenge) 05754 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 05755 memset(&ied, 0, sizeof(ied)); 05756 reg = iaxs[callno]->reg; 05757 if (reg) { 05758 if (inaddrcmp(®->addr, sin)) { 05759 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 05760 return -1; 05761 } 05762 if (ast_strlen_zero(reg->secret)) { 05763 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 05764 reg->regstate = REG_STATE_NOAUTH; 05765 return -1; 05766 } 05767 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 05768 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 05769 if (reg->secret[0] == '[') { 05770 char tmpkey[256]; 05771 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 05772 tmpkey[strlen(tmpkey) - 1] = '\0'; 05773 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL); 05774 } else 05775 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL); 05776 if (!res) { 05777 reg->regstate = REG_STATE_AUTHSENT; 05778 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 05779 } else 05780 return -1; 05781 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 05782 } else 05783 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 05784 return -1; 05785 }
| static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 4289 of file chan_iax2.c.
References REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REGSENT, REG_STATE_REJECTED, REG_STATE_TIMEOUT, and REG_STATE_UNREGISTERED.
Referenced by handle_response_register(), iax2_show_registry(), sip_reg_timeout(), and sip_show_registry().
04290 { 04291 switch(regstate) { 04292 case REG_STATE_UNREGISTERED: 04293 return "Unregistered"; 04294 case REG_STATE_REGSENT: 04295 return "Request Sent"; 04296 case REG_STATE_AUTHSENT: 04297 return "Auth. Sent"; 04298 case REG_STATE_REGISTERED: 04299 return "Registered"; 04300 case REG_STATE_REJECTED: 04301 return "Rejected"; 04302 case REG_STATE_TIMEOUT: 04303 return "Timeout"; 04304 case REG_STATE_NOAUTH: 04305 return "No Authentication"; 04306 default: 04307 return "Unknown"; 04308 } 04309 }
| static int reload | ( | void | ) | [static] |
Definition at line 9350 of file chan_iax2.c.
References reload_config().
09351 { 09352 return reload_config(); 09353 }
| static int reload_config | ( | void | ) | [static] |
Definition at line 9310 of file chan_iax2.c.
References ast_clear_flag, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, config, delete_users(), globalflags, iax2_do_register(), iax2_poke_peer(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, iax_provision_reload(), IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, prune_peers(), prune_users(), reload_firmware(), and set_config().
09311 { 09312 char *config = "iax.conf"; 09313 struct iax2_registry *reg; 09314 struct iax2_peer *peer; 09315 09316 strcpy(accountcode, ""); 09317 strcpy(language, ""); 09318 strcpy(mohinterpret, "default"); 09319 strcpy(mohsuggest, ""); 09320 amaflags = 0; 09321 delayreject = 0; 09322 ast_clear_flag((&globalflags), IAX_NOTRANSFER); 09323 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 09324 ast_clear_flag((&globalflags), IAX_USEJITTERBUF); 09325 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF); 09326 delete_users(); 09327 set_config(config, 1); 09328 prune_peers(); 09329 prune_users(); 09330 AST_LIST_LOCK(®istrations); 09331 AST_LIST_TRAVERSE(®istrations, reg, entry) 09332 iax2_do_register(reg); 09333 AST_LIST_UNLOCK(®istrations); 09334 /* Qualify hosts, too */ 09335 AST_LIST_LOCK(&peers); 09336 AST_LIST_TRAVERSE(&peers, peer, entry) 09337 iax2_poke_peer(peer, 0); 09338 AST_LIST_UNLOCK(&peers); 09339 reload_firmware(); 09340 iax_provision_reload(); 09341 09342 return 0; 09343 }
| static void reload_firmware | ( | void | ) | [static] |
Definition at line 1540 of file chan_iax2.c.
References ast_config_AST_DATA_DIR, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), iax_firmware::dead, destroy_firmware(), ast_firmware_list::lock, LOG_WARNING, iax_firmware::next, option_verbose, try_firmware(), VERBOSE_PREFIX_2, ast_firmware_list::wares, and waresl.
Referenced by load_module(), and reload_config().
01541 { 01542 struct iax_firmware *cur, *curl, *curp; 01543 DIR *fwd; 01544 struct dirent *de; 01545 char dir[256]; 01546 char fn[256]; 01547 /* Mark all as dead */ 01548 ast_mutex_lock(&waresl.lock); 01549 cur = waresl.wares; 01550 while(cur) { 01551 cur->dead = 1; 01552 cur = cur->next; 01553 } 01554 /* Now that we've freed them, load the new ones */ 01555 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR); 01556 fwd = opendir(dir); 01557 if (fwd) { 01558 while((de = readdir(fwd))) { 01559 if (de->d_name[0] != '.') { 01560 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 01561 if (!try_firmware(fn)) { 01562 if (option_verbose > 1) 01563 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name); 01564 } 01565 } 01566 } 01567 closedir(fwd); 01568 } else 01569 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 01570 01571 /* Clean up leftovers */ 01572 cur = waresl.wares; 01573 curp = NULL; 01574 while(cur) { 01575 curl = cur; 01576 cur = cur->next; 01577 if (curl->dead) { 01578 if (curp) { 01579 curp->next = cur; 01580 } else { 01581 waresl.wares = cur; 01582 } 01583 destroy_firmware(curl); 01584 } else { 01585 curp = cur; 01586 } 01587 } 01588 ast_mutex_unlock(&waresl.lock); 01589 }
Definition at line 6239 of file chan_iax2.c.
References iax_frame::callno, iax_rr::delay, iax_rr::dropped, iaxs, ies, iax_rr::jitter, iax_rr::losscnt, iax_rr::losspct, iax_rr::ooo, iax_rr::packets, and chan_iax2_pvt::remote_rr.
Referenced by socket_process().
06240 { 06241 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 06242 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 06243 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 06244 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 06245 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 06246 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 06247 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 06248 }
| static void* sched_thread | ( | void * | ignore | ) | [static] |
Definition at line 8120 of file chan_iax2.c.
References ast_cond_timedwait(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_runq(), ast_sched_wait(), ast_tvadd(), and sched.
Referenced by start_network_thread().
08121 { 08122 int count; 08123 int res; 08124 struct timeval tv; 08125 struct timespec ts; 08126 08127 for (;;) { 08128 res = ast_sched_wait(sched); 08129 if ((res > 1000) || (res < 0)) 08130 res = 1000; 08131 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000)); 08132 ts.tv_sec = tv.tv_sec; 08133 ts.tv_nsec = tv.tv_usec * 1000; 08134 08135 pthread_testcancel(); 08136 ast_mutex_lock(&sched_lock); 08137 ast_cond_timedwait(&sched_cond, &sched_lock, &ts); 08138 ast_mutex_unlock(&sched_lock); 08139 pthread_testcancel(); 08140 08141 count = ast_sched_runq(sched); 08142 if (count >= 20) 08143 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 08144 } 08145 return NULL; 08146 }
| static int schedule_delivery | ( | struct iax_frame * | fr, | |
| int | updatehistory, | |||
| int | fromtrunk, | |||
| unsigned int * | tsout | |||
| ) | [static] |
Definition at line 2318 of file chan_iax2.c.
References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_codec_get_samples(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_log(), ast_sched_del(), ast_test_flag, ast_tvadd(), calc_rxstamp(), iax_frame::callno, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, chan_iax2_pvt::jb, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, chan_iax2_pvt::jbid, len, LOG_DEBUG, chan_iax2_pvt::owner, ast_channel_tech::properties, chan_iax2_pvt::rxcore, sched, ast_channel::tech, iax_frame::ts, type, unwrap_timestamp(), and update_jbsched().
Referenced by socket_process().
02319 { 02320 int type, len; 02321 int ret; 02322 int needfree = 0; 02323 02324 /* Attempt to recover wrapped timestamps */ 02325 unwrap_timestamp(fr); 02326 02327 02328 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 02329 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 02330 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 02331 else { 02332 #if 0 02333 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 02334 #endif 02335 fr->af.delivery = ast_tv(0,0); 02336 } 02337 02338 type = JB_TYPE_CONTROL; 02339 len = 0; 02340 02341 if(fr->af.frametype == AST_FRAME_VOICE) { 02342 type = JB_TYPE_VOICE; 02343 len = ast_codec_get_samples(&fr->af) / 8; 02344 } else if(fr->af.frametype == AST_FRAME_CNG) { 02345 type = JB_TYPE_SILENCE; 02346 } 02347 02348 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 02349 if (tsout) 02350 *tsout = fr->ts; 02351 __do_deliver(fr); 02352 return -1; 02353 } 02354 02355 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 02356 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 02357 if( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && 02358 iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && 02359 (ast_bridged_channel(iaxs[fr->callno]->owner)->tech->properties & AST_CHAN_TP_WANTSJITTER)) { 02360 jb_frame frame; 02361 02362 /* deliver any frames in the jb */ 02363 while(jb_getall(iaxs[fr->callno]->jb,&frame) == JB_OK) 02364 __do_deliver(frame.data); 02365 02366 jb_reset(iaxs[fr->callno]->jb); 02367 02368 if (iaxs[fr->callno]->jbid > -1) 02369 ast_sched_del(sched, iaxs[fr->callno]->jbid); 02370 02371 iaxs[fr->callno]->jbid = -1; 02372 02373 /* deliver this frame now */ 02374 if (tsout) 02375 *tsout = fr->ts; 02376 __do_deliver(fr); 02377 return -1; 02378 } 02379 02380 /* insert into jitterbuffer */ 02381 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 02382 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 02383 calc_rxstamp(iaxs[fr->callno],fr->ts)); 02384 if (ret == JB_DROP) { 02385 needfree++; 02386 } else if (ret == JB_SCHED) { 02387 update_jbsched(iaxs[fr->callno]); 02388 } 02389 if (tsout) 02390 *tsout = fr->ts; 02391 if (needfree) { 02392 /* Free our iax frame */ 02393 iax2_frame_free(fr); 02394 return -1; 02395 } 02396 return 0; 02397 }
| static int send_command | ( | struct chan_iax2_pvt * | , | |
| char | , | |||
| int | , | |||
| unsigned | int, | |||
| const unsigned char * | , | |||
| int | , | |||
| int | ||||
| ) | [static] |
Definition at line 4572 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().
04573 { 04574 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 04575 }
| static int send_command_final | ( | struct chan_iax2_pvt * | , | |
| char | , | |||
| int | , | |||
| unsigned | int, | |||
| const unsigned char * | , | |||
| int | , | |||
| int | ||||
| ) | [static] |
Definition at line 4586 of file chan_iax2.c.
References __send_command(), chan_iax2_pvt::callno, and iax2_predestroy().
Referenced by __auth_reject(), __auto_hangup(), authenticate_request(), iax2_hangup(), socket_process(), and update_registry().
04587 { 04588 /* It is assumed that the callno has already been locked */ 04589 iax2_predestroy(i->callno); 04590 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 04591 }
| static int send_command_immediate | ( | struct chan_iax2_pvt * | , | |
| char | , | |||
| int | , | |||
| unsigned | int, | |||
| const unsigned char * | , | |||
| int | , | |||
| int | ||||
| ) | [static] |
Definition at line 4593 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
04594 { 04595 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 04596 }
| static int send_command_locked | ( | unsigned short | callno, | |
| char | , | |||
| int | , | |||
| unsigned | int, | |||
| const unsigned char * | , | |||
| int | , | |||
| int | ||||
| ) | [static] |
Definition at line 4577 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().
04578 { 04579 int res; 04580 ast_mutex_lock(&iaxsl[callno]); 04581 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 04582 ast_mutex_unlock(&iaxsl[callno]); 04583 return res; 04584 }
| static int send_command_transfer | ( | struct chan_iax2_pvt * | , | |
| char | , | |||
| int | , | |||
| unsigned | int, | |||
| const unsigned char * | , | |||
| int | ||||
| ) | [static] |
Definition at line 4598 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
04599 { 04600 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 04601 }
| static int send_lagrq | ( | void * | data | ) | [static] |
Definition at line 960 of file chan_iax2.c.
References __send_lagrq(), and schedule_action.
Referenced by __send_lagrq(), find_callno(), and make_trunk().
00961 { 00962 #ifdef SCHED_MULTITHREADED 00963 if (schedule_action(__send_lagrq, data)) 00964 #endif 00965 __send_lagrq(data); 00966 return 0; 00967 }
| static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 1654 of file chan_iax2.c.
References chan_iax2_pvt::addr, ast_backtrace(), ast_inet_ntoa(), ast_log(), error(), f, handle_error(), iax_showframe(), iaxs, LOG_DEBUG, LOG_ERROR, option_debug, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, and transfer.
Referenced by __attempt_transmit(), iax2_send(), network_thread(), and vnak_retransmit().
01655 { 01656 int res; 01657 int callno; 01658 01659 if( f == NULL ) { 01660 ast_log(LOG_ERROR, "send_packet( NULL )\n"); 01661 ast_backtrace(); 01662 return -1; 01663 } 01664 01665 callno = f->callno; 01666 01667 /* Don't send if there was an error, but return error instead */ 01668 if (!callno || !iaxs[callno] || iaxs[callno]->error) 01669 return -1; 01670 01671 /* Called with iaxsl held */ 01672 if (option_debug > 2 && iaxdebug) 01673 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)); 01674 if (f->transfer) { 01675 if (iaxdebug) 01676 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 01677 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, 01678 sizeof(iaxs[callno]->transfer)); 01679 } else { 01680 if (iaxdebug) 01681 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 01682 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, 01683 sizeof(iaxs[callno]->addr)); 01684 } 01685 if (res < 0) { 01686 if (option_debug && iaxdebug) 01687 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 01688 handle_error(); 01689 } else 01690 res = 0; 01691 return res; 01692 }
| static int send_ping | ( | void * | data | ) | [static] |
Definition at line 925 of file chan_iax2.c.
References __send_ping(), and schedule_action.
Referenced by __send_ping(), find_callno(), and make_trunk().
00926 { 00927 #ifdef SCHED_MULTITHREADED 00928 if (schedule_action(__send_ping, data)) 00929 #endif 00930 __send_ping(data); 00931 return 0; 00932 }
| static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
| struct timeval * | now | |||
| ) | [static] |
Definition at line 5924 of file chan_iax2.c.
References iax2_trunk_peer::addr, iax_frame::afdata, ast_inet_ntoa(), ast_log(), ast_test_flag, calc_txpeerstamp(), iax2_trunk_peer::calls, ast_iax2_meta_hdr::cmddata, iax_frame::data, ast_iax2_meta_hdr::data, iax_frame::datalen, iax_frame::direction, DIRECTION_OUTGRESS, globalflags, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_hdr::metacmd, iax_frame::retrans, iax2_trunk_peer::sockfd, iax_frame::transfer, transmit_trunk(), iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdatalen, ast_iax2_meta_trunk_hdr::ts, and ast_iax2_meta_hdr::zeros.
Referenced by timing_read().
05925 { 05926 int res = 0; 05927 struct iax_frame *fr; 05928 struct ast_iax2_meta_hdr *meta; 05929 struct ast_iax2_meta_trunk_hdr *mth; 05930 int calls = 0; 05931 05932 /* Point to frame */ 05933 fr = (struct iax_frame *)tpeer->trunkdata; 05934 /* Point to meta data */ 05935 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 05936 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 05937 if (tpeer->trunkdatalen) { 05938 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 05939 meta->zeros = 0; 05940 meta->metacmd = IAX_META_TRUNK; 05941 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 05942 meta->cmddata = IAX_META_TRUNK_MINI; 05943 else 05944 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 05945 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 05946 /* And the rest of the ast_iax2 header */ 05947 fr->direction = DIRECTION_OUTGRESS; 05948 fr->retrans = -1; 05949 fr->transfer = 0; 05950 /* Any appropriate call will do */ 05951 fr->data = fr->afdata; 05952 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 05953 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 05954 calls = tpeer->calls; 05955 #if 0 05956 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)); 05957 #endif 05958 /* Reset transmit trunk side data */ 05959 tpeer->trunkdatalen = 0; 05960 tpeer->calls = 0; 05961 } 05962 if (res < 0) 05963 return res; 05964 return calls; 05965 }
| static int set_config | ( | char * | config_file, | |
| int | reload | |||
| ) | [static] |
Load configuration.
Definition at line 8953 of file chan_iax2.c.
References ast_category_browse(), ast_cdr_amaflags2int(), ast_clear_flag, ast_config_destroy(), ast_config_load(), ast_context_create(), ast_context_find(), AST_LIST_INSERT_HEAD, 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(), DEFAULT_MAXMS, format, gen, get_encrypt_methods(), globalflags, iax2_register(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_CAPABILITY_LOWBANDWIDTH, IAX_CAPABILITY_MEDBANDWIDTH, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTUPDATE, IAX_TRANSFERMEDIA, IAX_TRUNKTIMESTAMPS, IAX_USEJITTERBUF, iaxmaxthreadcount, iaxthreadcount, io, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_variable::name, netsock, ast_variable::next, option_verbose, outsock, portno, prefs, reg_source_db(), set_timing(), socket_read(), ast_variable::value, and VERBOSE_PREFIX_2.
Referenced by load_module(), reload(), and reload_config().
08954 { 08955 struct ast_config *cfg, *ucfg; 08956 int capability=iax2_capability; 08957 struct ast_variable *v; 08958 char *cat; 08959 const char *utype; 08960 const char *tosval; 08961 int format; 08962 int portno = IAX_DEFAULT_PORTNO; 08963 int x; 08964 struct iax2_user *user; 08965 struct iax2_peer *peer; 08966 struct ast_netsock *ns; 08967 #if 0 08968 static unsigned short int last_port=0; 08969 #endif 08970 08971 cfg = ast_config_load(config_file); 08972 08973 if (!cfg) { 08974 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 08975 return -1; 08976 } 08977 08978 /* Reset global codec prefs */ 08979 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 08980 08981 /* Reset Global Flags */ 08982 memset(&globalflags, 0, sizeof(globalflags)); 08983 ast_set_flag(&globalflags, IAX_RTUPDATE); 08984 08985 #ifdef SO_NO_CHECK 08986 nochecksums = 0; 08987 #endif 08988 08989 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 08990 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 08991 08992 maxauthreq = 3; 08993 08994 v = ast_variable_browse(cfg, "general"); 08995 08996 /* Seed initial tos value */ 08997 tosval = ast_variable_retrieve(cfg, "general", "tos"); 08998 if (tosval) { 08999 if (ast_str2tos(tosval, &tos)) 09000 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n"); 09001 } 09002 while(v) { 09003 if (!strcasecmp(v->name, "bindport")){ 09004 if (reload) 09005 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 09006 else 09007 portno = atoi(v->value); 09008 } else if (!strcasecmp(v->name, "pingtime")) 09009 ping_time = atoi(v->value); 09010 else if (!strcasecmp(v->name, "iaxthreadcount")) { 09011 if (reload) { 09012 if (atoi(v->value) != iaxthreadcount) 09013 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 09014 } else { 09015 iaxthreadcount = atoi(v->value); 09016 if (iaxthreadcount < 1) { 09017 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 09018 iaxthreadcount = 1; 09019 } else if (iaxthreadcount > 256) { 09020 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 09021 iaxthreadcount = 256; 09022 } 09023 } 09024 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 09025 if (reload) { 09026 AST_LIST_LOCK(&dynamic_list); 09027 iaxmaxthreadcount = atoi(v->value); 09028 AST_LIST_UNLOCK(&dynamic_list); 09029 } else { 09030 iaxmaxthreadcount = atoi(v->value); 09031 if (iaxmaxthreadcount < 0) { 09032 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 09033 iaxmaxthreadcount = 0; 09034 } else if (iaxmaxthreadcount > 256) { 09035 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 09036 iaxmaxthreadcount = 256; 09037 } 09038 } 09039 } else if (!strcasecmp(v->name, "nochecksums")) { 09040 #ifdef SO_NO_CHECK 09041 if (ast_true(v->value)) 09042 nochecksums = 1; 09043 else 09044 nochecksums = 0; 09045 #else 09046 if (ast_true(v->value)) 09047 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 09048 #endif 09049 } 09050 else if (!strcasecmp(v->name, "maxjitterbuffer")) 09051 maxjitterbuffer = atoi(v->value); 09052 else if (!strcasecmp(v->name, "resyncthreshold")) 09053 resyncthreshold = atoi(v->value); 09054 else if (!strcasecmp(v->name, "maxjitterinterps")) 09055 maxjitterinterps = atoi(v->value); 09056 else if (!strcasecmp(v->name, "lagrqtime")) 09057 lagrq_time = atoi(v->value); 09058 else if (!strcasecmp(v->name, "maxregexpire")) 09059 max_reg_expire = atoi(v->value); 09060 else if (!strcasecmp(v->name, "minregexpire")) 09061 min_reg_expire = atoi(v->value); 09062 else if (!strcasecmp(v->name, "bindaddr")) { 09063 if (reload) { 09064 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 09065 } else { 09066 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) { 09067 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 09068 } else { 09069 if (option_verbose > 1) { 09070 if (strchr(v->value, ':')) 09071 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value); 09072 else 09073 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno); 09074 } 09075 if (defaultsockfd < 0) 09076 defaultsockfd = ast_netsock_sockfd(ns); 09077 ast_netsock_unref(ns); 09078 } 09079 } 09080 } else if (!strcasecmp(v->name, "authdebug")) 09081 authdebug = ast_true(v->value); 09082 else if (!strcasecmp(v->name, "encryption")) 09083 iax2_encryption = get_encrypt_methods(v->value); 09084 else if (!strcasecmp(v->name, "notransfer")) { 09085 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09086 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 09087 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER); 09088 } else if (!strcasecmp(v->name, "transfer")) { 09089 if (!strcasecmp(v->value, "mediaonly")) { 09090 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09091 } else if (ast_true(v->value)) { 09092 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09093 } else 09094 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09095 } else if (!strcasecmp(v->name, "codecpriority")) { 09096 if(!strcasecmp(v->value, "caller")) 09097 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 09098 else if(!strcasecmp(v->value, "disabled")) 09099 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 09100 else if(!strcasecmp(v->value, "reqonly")) { 09101 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 09102 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 09103 } 09104 } else if (!strcasecmp(v->name, "jitterbuffer")) 09105 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 09106 else if (!strcasecmp(v->name, "forcejitterbuffer")) 09107 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 09108 else if (!strcasecmp(v->name, "delayreject")) 09109 delayreject = ast_true(v->value); 09110 else if (!strcasecmp(v->name, "rtcachefriends")) 09111 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 09112 else if (!strcasecmp(v->name, "rtignoreregexpire")) 09113 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 09114 else if (!strcasecmp(v->name, "rtupdate")) 09115 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 09116 else if (!strcasecmp(v->name, "trunktimestamps")) 09117 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 09118 else if (!strcasecmp(v->name, "rtautoclear")) { 09119 int i = atoi(v->value); 09120 if(i > 0) 09121 global_rtautoclear = i; 09122 else 09123 i = 0; 09124 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 09125 } else if (!strcasecmp(v->name, "trunkfreq")) { 09126 trunkfreq = atoi(v->value); 09127 if (trunkfreq < 10) 09128 trunkfreq = 10; 09129 } else if (!strcasecmp(v->name, "autokill")) { 09130 if (sscanf(v->value, "%d", &x) == 1) { 09131 if (x >= 0) 09132 autokill = x; 09133 else 09134 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 09135 } else if (ast_true(v->value)) { 09136 autokill = DEFAULT_MAXMS; 09137 } else { 09138 autokill = 0; 09139 } 09140 } else if (!strcasecmp(v->name, "bandwidth")) { 09141 if (!strcasecmp(v->value, "low")) { 09142 capability = IAX_CAPABILITY_LOWBANDWIDTH; 09143 } else if (!strcasecmp(v->value, "medium")) { 09144 capability = IAX_CAPABILITY_MEDBANDWIDTH; 09145 } else if (!strcasecmp(v->value, "high")) { 09146 capability = IAX_CAPABILITY_FULLBANDWIDTH; 09147 } else 09148 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 09149 } else if (!strcasecmp(v->name, "allow")) { 09150 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 09151 } else if (!strcasecmp(v->name, "disallow")) { 09152 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 09153 } else if (!strcasecmp(v->name, "register")) { 09154 iax2_register(v->value, v->lineno); 09155 } else if (!strcasecmp(v->name, "iaxcompat")) { 09156 iaxcompat = ast_true(v->value); 09157 } else if (!strcasecmp(v->name, "regcontext")) { 09158 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 09159 /* Create context if it doesn't exist already */ 09160 if (!ast_context_find(regcontext)) 09161 ast_context_create(NULL, regcontext, "IAX2"); 09162 } else if (!strcasecmp(v->name, "tos")) { 09163 if (ast_str2tos(v->value, &tos)) 09164 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno); 09165 } else if (!strcasecmp(v->name, "accountcode")) { 09166 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 09167 } else if (!strcasecmp(v->name, "mohinterpret")) { 09168 ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret)); 09169 } else if (!strcasecmp(v->name, "mohsuggest")) { 09170 ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest)); 09171 } else if (!strcasecmp(v->name, "amaflags")) { 09172 format = ast_cdr_amaflags2int(v->value); 09173 if (format < 0) { 09174 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 09175 } else { 09176 amaflags = format; 09177 } 09178 } else if (!strcasecmp(v->name, "language")) { 09179 ast_copy_string(language, v->value, sizeof(language)); 09180 } else if (!strcasecmp(v->name, "maxauthreq")) { 09181 maxauthreq = atoi(v->value); 09182 if (maxauthreq < 0) 09183 maxauthreq = 0; 09184 } else if (!strcasecmp(v->name, "adsi")) { 09185 adsi = ast_true(v->value); 09186 } /*else if (strcasecmp(v->name,"type")) */ 09187 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09188 v = v->next; 09189 } 09190 09191 if (defaultsockfd < 0) { 09192 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) { 09193 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 09194 } else { 09195 if (option_verbose > 1) 09196 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 09197 defaultsockfd = ast_netsock_sockfd(ns); 09198 ast_netsock_unref(ns); 09199 } 09200 } 09201 if (reload) { 09202 ast_netsock_release(outsock); 09203 outsock = ast_netsock_list_alloc(); 09204 if (!outsock) { 09205 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 09206 return -1; 09207 } 09208 ast_netsock_init(outsock); 09209 } 09210 09211 if (min_reg_expire > max_reg_expire) { 09212 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 09213 min_reg_expire, max_reg_expire, max_reg_expire); 09214 min_reg_expire = max_reg_expire; 09215 } 09216 iax2_capability = capability; 09217 09218 ucfg = ast_config_load("users.conf"); 09219 if (ucfg) { 09220 struct ast_variable *gen; 09221 int genhasiax; 09222 int genregisteriax; 09223 const char *hasiax, *registeriax; 09224 09225 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 09226 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 09227 gen = ast_variable_browse(ucfg, "general"); 09228 cat = ast_category_browse(ucfg, NULL); 09229 while (cat) { 09230 if (strcasecmp(cat, "general")) { 09231 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 09232 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 09233 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 09234 /* Start with general parameters, then specific parameters, user and peer */ 09235 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 09236 if (user) { 09237 AST_LIST_LOCK(&users); 09238 AST_LIST_INSERT_HEAD(&users, user, entry); 09239 AST_LIST_UNLOCK(&users); 09240 } 09241 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 09242 if (peer) { 09243 AST_LIST_LOCK(&peers); 09244 AST_LIST_INSERT_HEAD(&peers, peer, entry); 09245 AST_LIST_UNLOCK(&peers); 09246 if (ast_test_flag(peer, IAX_DYNAMIC)) 09247 reg_source_db(peer); 09248 } 09249 } 09250 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 09251 char tmp[256]; 09252 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 09253 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 09254 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 09255 if (!host) 09256 host = ast_variable_retrieve(ucfg, "general", "host"); 09257 if (!username) 09258 username = ast_variable_retrieve(ucfg, "general", "username"); 09259 if (!secret) 09260 secret = ast_variable_retrieve(ucfg, "general", "secret"); 09261 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 09262 if (!ast_strlen_zero(secret)) 09263 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 09264 else 09265 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 09266 iax2_register(tmp, 0); 09267 } 09268 } 09269 } 09270 cat = ast_category_browse(ucfg, cat); 09271 } 09272 ast_config_destroy(ucfg); 09273 } 09274 09275 cat = ast_category_browse(cfg, NULL); 09276 while(cat) { 09277 if (strcasecmp(cat, "general")) { 09278 utype = ast_variable_retrieve(cfg, cat, "type"); 09279 if (utype) { 09280 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 09281 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 09282 if (user) { 09283 AST_LIST_LOCK(&users); 09284 AST_LIST_INSERT_HEAD(&users, user, entry); 09285 AST_LIST_UNLOCK(&users); 09286 } 09287 } 09288 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 09289 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 09290 if (peer) { 09291 AST_LIST_LOCK(&peers); 09292 AST_LIST_INSERT_HEAD(&peers, peer, entry); 09293 AST_LIST_UNLOCK(&peers); 09294 if (ast_test_flag(peer, IAX_DYNAMIC)) 09295 reg_source_db(peer); 09296 } 09297 } else if (strcasecmp(utype, "user")) { 09298 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 09299 } 09300 } else 09301 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 09302 } 09303 cat = ast_category_browse(cfg, cat); 09304 } 09305 ast_config_destroy(cfg); 09306 set_timing(); 09307 return capability; 09308 }
| static void set_timing | ( | void | ) | [static] |
Definition at line 8936 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by set_config().
08937 { 08938 #ifdef HAVE_ZAPTEL 08939 int bs = trunkfreq * 8; 08940 if (timingfd > -1) { 08941 if ( 08942 #ifdef ZT_TIMERACK 08943 ioctl(timingfd, ZT_TIMERCONFIG, &bs) && 08944 #endif 08945 ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs)) 08946 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n"); 08947 } 08948 #endif 08949 }
| static void signal_condition | ( | ast_mutex_t * | lock, | |
| ast_cond_t * | cond | |||
| ) | [static] |
Definition at line 712 of file chan_iax2.c.
References ast_cond_signal(), ast_mutex_lock(), and ast_mutex_unlock().
Referenced by __schedule_action(), iax2_transmit(), network_thread(), socket_read(), and update_jbsched().
00713 { 00714 ast_mutex_lock(lock); 00715 ast_cond_signal(cond); 00716 ast_mutex_unlock(lock); 00717 }
| static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 6316 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, ast_async_goto(), ast_best_codec(), ast_bridged_channel(), AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_clear_flag, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_UNHOLD, ast_device_state_changed(), ast_exists_extension(), AST_FORMAT_SLINEAR, ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_IAX, AST_FRAME_NULL, AST_FRAME_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_queue_control(), ast_queue_control_data(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_variables_destroy(), ast_verbose(), auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, calc_timestamp(), iax2_peer::callno, iax2_dpcache::callno, chan_iax2_pvt::callno, iax_frame::callno, ast_iax2_mini_hdr::callno, check_access(), check_provisioning(), complete_dpreply(), complete_transfer(), construct_rr(), ast_channel::context, decrypt_frame(), dp_lookup(), EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, f, iax_frame::final, find_callno(), find_tpeer(), fix_peerts(), iax2_dpcache::flags, format, chan_iax2_pvt::frames_received, free, iax2_peer::historicms, iax2_ack_registry(), iax2_destroy(), iax2_dprequest(), iax2_poke_peer_s(), iax2_send(), iax2_vnak(), IAX_ALREADYGONE, IAX_AUTH_MD5, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_NEW, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXMEDIA, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, IAX_COMMAND_VNAK, IAX_ENCRYPTED, iax_firmware_append(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, iax_frame_wrap(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLNO, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_FORMAT, IAX_IE_IAX_UNKNOWN, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, iax_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, iax_showframe(), IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_STATE_UNCHANGED, IAX_TRUNK, iaxfrdup2(), iaxq, iaxs, iaxsl, ies, inaddrcmp(), chan_iax2_pvt::initid, chan_iax2_pvt::iseqno, chan_iax2_pvt::last, iax2_peer::lastms, ast_iax2_meta_trunk_mini::len, len, ast_channel::lock, iax2_trunk_peer::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_trunk(), manager_event(), iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, ast_iax2_meta_trunk_mini::mini, NEW_ALLOW, NEW_PREVENT, option_debug, option_verbose, iax_frame::oseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), iax2_dpcache::peer, chan_iax2_pvt::peercallno, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, raw_hangup(), REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), iax_frame::retries, chan_iax2_pvt::rseqno, iax2_trunk_peer::rxtrunktime, S_OR, save_rr(), sched, schedule_delivery(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), iax2_peer::smoothing, spawn_dp_lookup(), chan_iax2_pvt::state, stop_stuff(), thread, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MREADY, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, iax2_trunk_peer::trunkact, try_transfer(), iax_frame::ts, ast_iax2_mini_hdr::ts, uncompress_subclass(), update_registry(), var, VERBOSE_PREFIX_3, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, and ast_iax2_meta_hdr::zeros.
06317 { 06318 struct sockaddr_in sin; 06319 int res; 06320 int updatehistory=1; 06321 int new = NEW_PREVENT; 06322 void *ptr; 06323 int dcallno = 0; 06324 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 06325 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 06326 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 06327 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 06328 struct ast_iax2_meta_trunk_hdr *mth; 06329 struct ast_iax2_meta_trunk_entry *mte; 06330 struct ast_iax2_meta_trunk_mini *mtm; 06331 struct iax_frame *fr; 06332 struct iax_frame *cur; 06333 struct ast_frame f = { 0, }; 06334 struct ast_channel *c; 06335 struct iax2_dpcache *dp; 06336 struct iax2_peer *peer; 06337 struct iax2_trunk_peer *tpeer; 06338 struct timeval rxtrunktime; 06339 struct iax_ies ies; 06340 struct iax_ie_data ied0, ied1; 06341 int format; 06342 int fd; 06343 int exists; 06344 int minivid = 0; 06345 unsigned int ts; 06346 char empty[32]=""; /* Safety measure */ 06347 struct iax_frame *duped_fr; 06348 char host_pref_buf[128]; 06349 char caller_pref_buf[128]; 06350 struct ast_codec_pref pref; 06351 char *using_prefs = "mine"; 06352 06353 /* allocate an iax_frame with 4096 bytes of data buffer */ 06354 fr = alloca(sizeof(*fr) + 4096); 06355 fr->callno = 0; 06356 06357 /* Copy frequently used parameters to the stack */ 06358 res = thread->iores; 06359 fd = thread->iofd; 06360 memcpy(&sin, &thread->iosin, sizeof(sin)); 06361 06362 if (res < sizeof(*mh)) { 06363 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh)); 06364 return 1; 06365 } 06366 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 06367 if (res < sizeof(*vh)) { 06368 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)); 06369 return 1; 06370 } 06371 06372 /* This is a video frame, get call number */ 06373 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, 1, fd); 06374 minivid = 1; 06375 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) { 06376 unsigned char metatype; 06377 06378 if (res < sizeof(*meta)) { 06379 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)); 06380 return 1; 06381 } 06382 06383 /* This is a meta header */ 06384 switch(meta->metacmd) { 06385 case IAX_META_TRUNK: 06386 if (res < (sizeof(*meta) + sizeof(*mth))) { 06387 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res, 06388 sizeof(*meta) + sizeof(*mth)); 06389 return 1; 06390 } 06391 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 06392 ts = ntohl(mth->ts); 06393 metatype = meta->cmddata; 06394 res -= (sizeof(*meta) + sizeof(*mth)); 06395 ptr = mth->data; 06396 tpeer = find_tpeer(&sin, fd); 06397 if (!tpeer) { 06398 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)); 06399 return 1; 06400 } 06401 tpeer->trunkact = ast_tvnow(); 06402 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 06403 tpeer->rxtrunktime = tpeer->trunkact; 06404 rxtrunktime = tpeer->rxtrunktime; 06405 ast_mutex_unlock(&tpeer->lock); 06406 while(res >= sizeof(*mte)) { 06407 /* Process channels */ 06408 unsigned short callno, trunked_ts, len; 06409 06410 if (metatype == IAX_META_TRUNK_MINI) { 06411 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 06412 ptr += sizeof(*mtm); 06413 res -= sizeof(*mtm); 06414 len = ntohs(mtm->len); 06415 callno = ntohs(mtm->mini.callno); 06416 trunked_ts = ntohs(mtm->mini.ts); 06417 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 06418 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 06419 ptr += sizeof(*mte); 06420 res -= sizeof(*mte); 06421 len = ntohs(mte->len); 06422 callno = ntohs(mte->callno); 06423 trunked_ts = 0; 06424 } else { 06425 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 06426 break; 06427 } 06428 /* Stop if we don't have enough data */ 06429 if (len > res) 06430 break; 06431 fr->callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, 1, fd); 06432 if (fr->callno) { 06433 ast_mutex_lock(&iaxsl[fr->callno]); 06434 /* If it's a valid call, deliver the contents. If not, we 06435 drop it, since we don't have a scallno to use for an INVAL */ 06436 /* Process as a mini frame */ 06437 memset(&f, 0, sizeof(f)); 06438 f.frametype = AST_FRAME_VOICE; 06439 if (iaxs[fr->callno]) { 06440 if (iaxs[fr->callno]->voiceformat > 0) { 06441 f.subclass = iaxs[fr->callno]->voiceformat; 06442 f.datalen = len; 06443 if (f.datalen >= 0) { 06444 if (f.datalen) 06445 f.data = ptr; 06446 if(trunked_ts) { 06447 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 06448 } else 06449 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 06450 /* Don't pass any packets until we're started */ 06451 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 06452 /* Common things */ 06453 f.src = "IAX2"; 06454 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 06455 f.samples = ast_codec_get_samples(&f); 06456 iax_frame_wrap(fr, &f); 06457 duped_fr = iaxfrdup2(fr); 06458 if (duped_fr) { 06459 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); 06460 } 06461 /* It is possible for the pvt structure to go away after we call schedule_delivery */ 06462 if (fr && fr->callno && iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 06463 iaxs[fr->callno]->last = fr->ts; 06464 #if 1 06465 if (option_debug && iaxdebug) 06466 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 06467 #endif 06468 } 06469 } 06470 } else { 06471 ast_log(LOG_WARNING, "Datalen < 0?\n"); 06472 } 06473 } else { 06474 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n "); 06475 iax2_vnak(fr->callno); 06476 } 06477 } 06478 ast_mutex_unlock(&iaxsl[fr->callno]); 06479 } 06480 ptr += len; 06481 res -= len; 06482 } 06483 06484 } 06485 return 1; 06486 } 06487 06488 #ifdef DEBUG_SUPPORT 06489 if (iaxdebug && (res >= sizeof(*fh))) 06490 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 06491 #endif 06492 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06493 if (res < sizeof(*fh)) { 06494 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)); 06495 return 1; 06496 } 06497 06498 /* Get the destination call number */ 06499 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 06500 /* Retrieve the type and subclass */ 06501 f.frametype = fh->type; 06502 if (f.frametype == AST_FRAME_VIDEO) { 06503 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 06504 } else { 06505 f.subclass = uncompress_subclass(fh->csub); 06506 } 06507 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) || 06508 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) || 06509 (f.subclass == IAX_COMMAND_REGREL))) 06510 new = NEW_ALLOW; 06511 } else { 06512 /* Don't know anything about it yet */ 06513 f.frametype = AST_FRAME_NULL; 06514 f.subclass = 0; 06515 } 06516 06517 if (!fr->callno) 06518 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, 1, fd); 06519 06520 if (fr->callno > 0) 06521 ast_mutex_lock(&iaxsl[fr->callno]); 06522 06523 if (!fr->callno || !iaxs[fr->callno]) { 06524 /* A call arrived for a nonexistent destination. Unless it's an "inval" 06525 frame, reply with an inval */ 06526 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06527 /* We can only raw hangup control frames */ 06528 if (((f.subclass != IAX_COMMAND_INVAL) && 06529 (f.subclass != IAX_COMMAND_TXCNT) && 06530 (f.subclass != IAX_COMMAND_TXACC) && 06531 (f.subclass != IAX_COMMAND_FWDOWNL))|| 06532 (f.frametype != AST_FRAME_IAX)) 06533 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 06534 fd); 06535 } 06536 if (fr->callno > 0) 06537 ast_mutex_unlock(&iaxsl[fr->callno]); 06538 return 1; 06539 } 06540 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { 06541 if (decrypt_frame(fr->callno, fh, &f, &res)) { 06542 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 06543 ast_mutex_unlock(&iaxsl[fr->callno]); 06544 return 1; 06545 } 06546 #ifdef DEBUG_SUPPORT 06547 else if (iaxdebug) 06548 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 06549 #endif 06550 } 06551 06552 /* count this frame */ 06553 iaxs[fr->callno]->frames_received++; 06554 06555 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 06556 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 06557 f.subclass != IAX_COMMAND_TXACC) /* for attended transfer */ 06558 iaxs[fr->callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL); 06559 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 06560 if (option_debug && iaxdebug) 06561 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 06562 /* Check if it's out of order (and not an ACK or INVAL) */ 06563 fr->oseqno = fh->oseqno; 06564 fr->iseqno = fh->iseqno; 06565 fr->ts = ntohl(fh->ts); 06566 #ifdef IAXTESTS 06567 if (test_resync) { 06568 if (option_debug) 06569 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 06570 fr->ts += test_resync; 06571 } 06572 #endif /* IAXTESTS */ 06573 #if 0 06574 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 06575 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 06576 (f.subclass == IAX_COMMAND_NEW || 06577 f.subclass == IAX_COMMAND_AUTHREQ || 06578 f.subclass == IAX_COMMAND_ACCEPT || 06579 f.subclass == IAX_COMMAND_REJECT)) ) ) 06580 #endif 06581 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 06582 updatehistory = 0; 06583 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 06584 (iaxs[fr->callno]->iseqno || 06585 ((f.subclass != IAX_COMMAND_TXCNT) && 06586 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 06587 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 06588 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 06589 (f.subclass != IAX_COMMAND_TXACC)) || 06590 (f.frametype != AST_FRAME_IAX))) { 06591 if ( 06592 ((f.subclass != IAX_COMMAND_ACK) && 06593 (f.subclass != IAX_COMMAND_INVAL) && 06594 (f.subclass != IAX_COMMAND_TXCNT) && 06595 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 06596 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 06597 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 06598 (f.subclass != IAX_COMMAND_TXACC) && 06599 (f.subclass != IAX_COMMAND_VNAK)) || 06600 (f.frametype != AST_FRAME_IAX)) { 06601 /* If it's not an ACK packet, it's out of order. */ 06602 if (option_debug) 06603 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 06604 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); 06605 if (iaxs[fr->callno]->iseqno > fr->oseqno) { 06606 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 06607 if ((f.frametype != AST_FRAME_IAX) || 06608 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 06609 if (option_debug) 06610 ast_log(LOG_DEBUG, "Acking anyway\n"); 06611 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 06612 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 06613 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 06614 } 06615 } else { 06616 /* Send a VNAK requesting retransmission */ 06617 iax2_vnak(fr->callno); 06618 } 06619 ast_mutex_unlock(&iaxsl[fr->callno]); 06620 return 1; 06621 } 06622 } else { 06623 /* Increment unless it's an ACK or VNAK */ 06624 if (((f.subclass != IAX_COMMAND_ACK) && 06625 (f.subclass != IAX_COMMAND_INVAL) && 06626 (f.subclass != IAX_COMMAND_TXCNT) && 06627 (f.subclass != IAX_COMMAND_TXACC) && 06628 (f.subclass != IAX_COMMAND_VNAK)) || 06629 (f.frametype != AST_FRAME_IAX)) 06630 iaxs[fr->callno]->iseqno++; 06631 } 06632 /* A full frame */ 06633 if (res < sizeof(*fh)) { 06634 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh)); 06635 ast_mutex_unlock(&iaxsl[fr->callno]); 06636 return 1; 06637 } 06638 f.datalen = res - sizeof(*fh); 06639 06640 /* Handle implicit ACKing unless this is an INVAL, and only if this is 06641 from the real peer, not the transfer peer */ 06642 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 06643 ((f.subclass != IAX_COMMAND_INVAL) || 06644 (f.frametype != AST_FRAME_IAX))) { 06645 unsigned char x; 06646 /* XXX This code is not very efficient. Surely there is a better way which still 06647 properly handles boundary conditions? XXX */ 06648 /* First we have to qualify that the ACKed value is within our window */ 06649 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++) 06650 if (fr->iseqno == x) 06651 break; 06652 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 06653 /* The acknowledgement is within our window. Time to acknowledge everything 06654 that it says to */ 06655 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 06656 /* Ack the packet with the given timestamp */ 06657 if (option_debug && iaxdebug) 06658 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x); 06659 AST_LIST_LOCK(&iaxq.queue); 06660 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 06661 /* If it's our call, and our timestamp, mark -1 retries */ 06662 if ((fr->callno == cur->callno) && (x == cur->oseqno)) { 06663 cur->retries = -1; 06664 /* Destroy call if this is the end */ 06665 if (cur->final) { 06666 if (iaxdebug && option_debug) 06667 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", fr->callno); 06668 iax2_destroy(fr->callno); 06669 } 06670 } 06671 } 06672 AST_LIST_UNLOCK(&iaxq.queue); 06673 } 06674 /* Note how much we've received acknowledgement for */ 06675 if (iaxs[fr->callno]) 06676 iaxs[fr->callno]->rseqno = fr->iseqno; 06677 else { 06678 /* Stop processing now */ 06679 ast_mutex_unlock(&iaxsl[fr->callno]); 06680 return 1; 06681 } 06682 } else 06683 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 06684 } 06685 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 06686 ((f.frametype != AST_FRAME_IAX) || 06687 ((f.subclass != IAX_COMMAND_TXACC) && 06688 (f.subclass != IAX_COMMAND_TXCNT)))) { 06689 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 06690 ast_mutex_unlock(&iaxsl[fr->callno]); 06691 return 1; 06692 } 06693 06694 if (f.datalen) { 06695 if (f.frametype == AST_FRAME_IAX) { 06696 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) { 06697 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 06698 ast_mutex_unlock(&iaxsl[fr->callno]); 06699 return 1; 06700 } 06701 f.data = NULL; 06702 } else 06703 f.data = thread->buf + sizeof(*fh); 06704 } else { 06705 if (f.frametype == AST_FRAME_IAX) 06706 f.data = NULL; 06707 else 06708 f.data = empty; 06709 memset(&ies, 0, sizeof(ies)); 06710 } 06711 if (f.frametype == AST_FRAME_VOICE) { 06712 if (f.subclass != iaxs[fr->callno]->voiceformat) { 06713 iaxs[fr->callno]->voiceformat = f.subclass; 06714 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass); 06715 if (iaxs[fr->callno]->owner) { 06716 int orignative; 06717 retryowner: 06718 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 06719 ast_mutex_unlock(&iaxsl[fr->callno]); 06720 usleep(1); 06721 ast_mutex_lock(&iaxsl[fr->callno]); 06722 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner; 06723 } 06724 if (iaxs[fr->callno]) { 06725 if (iaxs[fr->callno]->owner) { 06726 orignative = iaxs[fr->callno]->owner->nativeformats; 06727 iaxs[fr->callno]->owner->nativeformats = f.subclass; 06728 if (iaxs[fr->callno]->owner->readformat) 06729 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 06730 iaxs[fr->callno]->owner->nativeformats = orignative; 06731 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 06732 } 06733 } else { 06734 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); 06735 /* Free remote variables (if any) */ 06736 if (ies.vars) 06737 ast_variables_destroy(ies.vars); 06738 ast_mutex_unlock(&iaxsl[fr->callno]); 06739 return 1; 06740 } 06741 } 06742 } 06743 } 06744 if (f.frametype == AST_FRAME_VIDEO) { 06745 if (f.subclass != iaxs[fr->callno]->videoformat) { 06746 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 06747 iaxs[fr->callno]->videoformat = f.subclass & ~0x1; 06748 } 06749 } 06750 if (f.frametype == AST_FRAME_IAX) { 06751 if (iaxs[fr->callno]->initid > -1) { 06752 /* Don't auto congest anymore since we've gotten something usefulb ack */ 06753 ast_sched_del(sched, iaxs[fr->callno]->initid); 06754 iaxs[fr->callno]->initid = -1; 06755 } 06756 /* Handle the IAX pseudo frame itself */ 06757 if (option_debug && iaxdebug) 06758 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); 06759 06760 /* Update last ts unless the frame's timestamp originated with us. */ 06761 if (iaxs[fr->callno]->last < fr->ts && 06762 f.subclass != IAX_COMMAND_ACK && 06763 f.subclass != IAX_COMMAND_PONG && 06764 f.subclass != IAX_COMMAND_LAGRP) { 06765 iaxs[fr->callno]->last = fr->ts; 06766 if (option_debug && iaxdebug) 06767 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 06768 } 06769 06770 switch(f.subclass) { 06771 case IAX_COMMAND_ACK: 06772 /* Do nothing */ 06773 break; 06774 case IAX_COMMAND_QUELCH: 06775 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 06776 /* Generate Manager Hold event, if necessary*/ 06777 if (iaxs[fr->callno]->owner) { 06778 manager_event(EVENT_FLAG_CALL, "Hold", 06779 "Channel: %s\r\n" 06780 "Uniqueid: %s\r\n", 06781 iaxs[fr->callno]->owner->name, 06782 iaxs[fr->callno]->owner->uniqueid); 06783 } 06784 06785 ast_set_flag(iaxs[fr->callno], IAX_QUELCH); 06786 if (ies.musiconhold) { 06787 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 06788 const char *mohsuggest = iaxs[fr->callno]->mohsuggest; 06789 ast_queue_control_data(iaxs[fr->callno]->owner, AST_CONTROL_HOLD, 06790 S_OR(mohsuggest, NULL), 06791 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0); 06792 } 06793 } 06794 } 06795 break; 06796 case IAX_COMMAND_UNQUELCH: 06797 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 06798 /* Generate Manager Unhold event, if necessary*/ 06799 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { 06800 manager_event(EVENT_FLAG_CALL, "Unhold", 06801 "Channel: %s\r\n" 06802 "Uniqueid: %s\r\n", 06803 iaxs[fr->callno]->owner->name, 06804 iaxs[fr->callno]->owner->uniqueid); 06805 } 06806 06807 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); 06808 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) 06809 ast_queue_control(iaxs[fr->callno]->owner, AST_CONTROL_UNHOLD); 06810 } 06811 break; 06812 case IAX_COMMAND_TXACC: 06813 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 06814 /* Ack the packet with the given timestamp */ 06815 AST_LIST_LOCK(&iaxq.queue); 06816 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 06817 /* Cancel any outstanding txcnt's */ 06818 if ((fr->callno == cur->callno) && (cur->transfer)) 06819 cur->retries = -1; 06820 } 06821 AST_LIST_UNLOCK(&iaxq.queue); 06822 memset(&ied1, 0, sizeof(ied1)); 06823 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 06824 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 06825 iaxs[fr->callno]->transferring = TRANSFER_READY; 06826 } 06827 break; 06828 case IAX_COMMAND_NEW: 06829 /* Ignore if it's already up */ 06830 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 06831 break; 06832 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) 06833 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 06834 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 06835 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { 06836 fr->callno = make_trunk(fr->callno, 1); 06837 } 06838 /* For security, always ack immediately */ 06839 if (delayreject) 06840 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 06841 if (check_access(fr->callno, &sin, &ies)) { 06842 /* They're not allowed on */ 06843 auth_fail(fr->callno, IAX_COMMAND_REJECT); 06844 if (authdebug) 06845 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); 06846 break; 06847 } 06848 /* This might re-enter the IAX code and need the lock */ 06849 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 06850 ast_mutex_unlock(&iaxsl[fr->callno]); 06851 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 06852 ast_mutex_lock(&iaxsl[fr->callno]); 06853 } else 06854 exists = 0; 06855 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 06856 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 06857 memset(&ied0, 0, sizeof(ied0)); 06858 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 06859 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 06860 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 06861 if (authdebug) 06862 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); 06863 } else { 06864 /* Select an appropriate format */ 06865 06866 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 06867 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 06868 using_prefs = "reqonly"; 06869 } else { 06870 using_prefs = "disabled"; 06871 } 06872 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 06873 memset(&pref, 0, sizeof(pref)); 06874 strcpy(caller_pref_buf, "disabled"); 06875 strcpy(host_pref_buf, "disabled"); 06876 } else { 06877 using_prefs = "mine"; 06878 /* If the information elements are in here... use them */ 06879 if (ies.codec_prefs) 06880 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 06881 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 06882 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 06883 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 06884 pref = iaxs[fr->callno]->rprefs; 06885 using_prefs = "caller"; 06886 } else { 06887 pref = iaxs[fr->callno]->prefs; 06888 } 06889 } else 06890 pref = iaxs[fr->callno]->prefs; 06891 06892 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 06893 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 06894 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 06895 } 06896 if (!format) { 06897 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 06898 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 06899 if (!format) { 06900 memset(&ied0, 0, sizeof(ied0)); 06901 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 06902 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 06903 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 06904 if (authdebug) { 06905 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 06906 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); 06907 else 06908 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); 06909 } 06910 } else { 06911 /* Pick one... */ 06912 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 06913 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 06914 format = 0; 06915 } else { 06916 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 06917 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 06918 memset(&pref, 0, sizeof(pref)); 06919 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 06920 strcpy(caller_pref_buf,"disabled"); 06921 strcpy(host_pref_buf,"disabled"); 06922 } else { 06923 using_prefs = "mine"; 06924 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 06925 /* Do the opposite of what we tried above. */ 06926 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 06927 pref = iaxs[fr->callno]->prefs; 06928 } else { 06929 pref = iaxs[fr->callno]->rprefs; 06930 using_prefs = "caller"; 06931 } 06932 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 06933 06934 } else /* if no codec_prefs IE do it the old way */ 06935 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 06936 } 06937 } 06938 06939 if (!format) { 06940 memset(&ied0, 0, sizeof(ied0)); 06941 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 06942 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 06943 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 06944 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 06945 if (authdebug) 06946 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); 06947 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 06948 break; 06949 } 06950 } 06951 } 06952 if (format) { 06953 /* No authentication required, let them in */ 06954 memset(&ied1, 0, sizeof(ied1)); 06955 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 06956 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 06957 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 06958 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 06959 if (option_verbose > 2) 06960 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" 06961 "%srequested format = %s,\n" 06962 "%srequested prefs = %s,\n" 06963 "%sactual format = %s,\n" 06964 "%shost prefs = %s,\n" 06965 "%spriority = %s\n", 06966 ast_inet_ntoa(sin.sin_addr), 06967 VERBOSE_PREFIX_4, 06968 ast_getformatname(iaxs[fr->callno]->peerformat), 06969 VERBOSE_PREFIX_4, 06970 caller_pref_buf, 06971 VERBOSE_PREFIX_4, 06972 ast_getformatname(format), 06973 VERBOSE_PREFIX_4, 06974 host_pref_buf, 06975 VERBOSE_PREFIX_4, 06976 using_prefs); 06977 06978 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 06979 iax2_destroy(fr->callno); 06980 else if (ies.vars) { 06981 struct ast_variable *var, *prev = NULL; 06982 char tmp[256]; 06983 for (var = ies.vars; var; var = var->next) { 06984 if (prev) 06985 free(prev); 06986 prev = var; 06987 snprintf(tmp, sizeof(tmp), "__~IAX2~%s", var->name); 06988 pbx_builtin_setvar_helper(c, tmp, var->value); 06989 } 06990 ies.vars = NULL; 06991 } 06992 } else { 06993 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 06994 /* If this is a TBD call, we're ready but now what... */ 06995 if (option_verbose > 2) 06996 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 06997 } 06998 } 06999 } 07000 break; 07001 } 07002 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 07003 merge_encryption(iaxs[fr->callno],ies.encmethods); 07004 else 07005 iaxs[fr->callno]->encmethods = 0; 07006 if (!authenticate_request(iaxs[fr->callno])) 07007 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 07008 break; 07009 case IAX_COMMAND_DPREQ: 07010 /* Request status in the dialplan */ 07011 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 07012 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 07013 if (iaxcompat) { 07014 /* Spawn a thread for the lookup */ 07015 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 07016 } else { 07017 /* Just look it up */ 07018 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 07019 } 07020 } 07021 break; 07022 case IAX_COMMAND_HANGUP: 07023 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07024 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno); 07025 /* Set hangup cause according to remote */ 07026 if (ies.causecode && iaxs[fr->callno]->owner) 07027 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07028 /* Send ack immediately, before we destroy */ 07029 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07030 iax2_destroy(fr->callno); 07031 break; 07032 case IAX_COMMAND_REJECT: 07033 /* Set hangup cause according to remote */ 07034 if (ies.causecode && iaxs[fr->callno]->owner) 07035 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 07036 07037 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07038 if (iaxs[fr->callno]->owner && authdebug) 07039 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 07040 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 07041 ies.cause ? ies.cause : "<Unknown>"); 07042 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", 07043 fr->callno); 07044 } 07045 /* Send ack immediately, before we destroy */ 07046 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 07047 fr->ts, NULL, 0, fr->iseqno); 07048 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) 07049 iaxs[fr->callno]->error = EPERM; 07050 iax2_destroy(fr->callno); 07051 break; 07052 case IAX_COMMAND_TRANSFER: 07053 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && ies.called_number) { 07054 /* Set BLINDTRANSFER channel variables */ 07055 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", ast_bridged_channel(iaxs[fr->callno]->owner)->name); 07056 pbx_builtin_setvar_helper(ast_bridged_channel(iaxs[fr->callno]->owner), "BLINDTRANSFER", iaxs[fr->callno]->owner->name); 07057 if (!strcmp(ies.called_number, ast_parking_ext())) { 07058 if (iax_park(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->owner)) { 07059 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name); 07060 } else if (ast_bridged_channel(iaxs[fr->callno]->owner)) 07061 ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name); 07062 } else { 07063 if (ast_async_goto(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->context, ies.called_number, 1)) 07064 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 07065 ies.called_number, iaxs[fr->callno]->context); 07066 else 07067 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 07068 ies.called_number, iaxs[fr->callno]->context); 07069 } 07070 } else 07071 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno); 07072 break; 07073 case IAX_COMMAND_ACCEPT: 07074 /* Ignore if call is already up or needs authentication or is a TBD */ 07075 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 07076 break; 07077 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 07078 /* Send ack immediately, before we destroy */ 07079 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07080 iax2_destroy(fr->callno); 07081 break; 07082 } 07083 if (ies.format) { 07084 iaxs[fr->callno]->peerformat = ies.format; 07085 } else { 07086 if (iaxs[fr->callno]->owner) 07087 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 07088 else 07089 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 07090 } 07091 if (option_verbose > 2) 07092 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)); 07093 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 07094 memset(&ied0, 0, sizeof(ied0)); 07095 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07096 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07097 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07098 if (authdebug) 07099 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); 07100 } else { 07101 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07102 if (iaxs[fr->callno]->owner) { 07103 /* Switch us to use a compatible format */ 07104 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 07105 if (option_verbose > 2) 07106 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 07107 retryowner2: 07108 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07109 ast_mutex_unlock(&iaxsl[fr->callno]); 07110 usleep(1); 07111 ast_mutex_lock(&iaxsl[fr->callno]); 07112 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2; 07113 } 07114 07115 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 07116 /* Setup read/write formats properly. */ 07117 if (iaxs[fr->callno]->owner->writeformat) 07118 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 07119 if (iaxs[fr->callno]->owner->readformat) 07120 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07121 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07122 } 07123 } 07124 } 07125 if (iaxs[fr->callno]) { 07126 ast_mutex_lock(&dpcache_lock); 07127 dp = iaxs[fr->callno]->dpentries; 07128 while(dp) { 07129 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) { 07130 iax2_dprequest(dp, fr->callno); 07131 } 07132 dp = dp->peer; 07133 } 07134 ast_mutex_unlock(&dpcache_lock); 07135 } 07136 break; 07137 case IAX_COMMAND_POKE: 07138 /* Send back a pong packet with the original timestamp */ 07139 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 07140 break; 07141 case IAX_COMMAND_PING: 07142 { 07143 struct iax_ie_data pingied; 07144 construct_rr(iaxs[fr->callno], &pingied); 07145 /* Send back a pong packet with the original timestamp */ 07146 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 07147 } 07148 break; 07149 case IAX_COMMAND_PONG: 07150 /* Calculate ping time */ 07151 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 07152 /* save RR info */ 07153 save_rr(fr, &ies); 07154 07155 if (iaxs[fr->callno]->peerpoke) { 07156 peer = iaxs[fr->callno]->peerpoke; 07157 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 07158 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 07159 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 07160 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07161 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07162 } 07163 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 07164 if (iaxs[fr->callno]->pingtime > peer->maxms) { 07165 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 07166 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 07167 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 07168 } 07169 } 07170 peer->lastms = iaxs[fr->callno]->pingtime; 07171 if (peer->smoothing && (peer->lastms > -1)) 07172 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 07173 else if (peer->smoothing && peer->lastms < 0) 07174 peer->historicms = (0 + peer->historicms) / 2; 07175 else 07176 peer->historicms = iaxs[fr->callno]->pingtime; 07177 07178 /* Remove scheduled iax2_poke_noanswer */ 07179 if (peer->pokeexpire > -1) 07180 ast_sched_del(sched, peer->pokeexpire); 07181 /* Schedule the next cycle */ 07182 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 07183 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer); 07184 else 07185 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer); 07186 /* and finally send the ack */ 07187 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07188 /* And wrap up the qualify call */ 07189 iax2_destroy(fr->callno); 07190 peer->callno = 0; 07191 if (option_debug) 07192 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 07193 } 07194 break; 07195 case IAX_COMMAND_LAGRQ: 07196 case IAX_COMMAND_LAGRP: 07197 f.src = "LAGRQ"; 07198 f.mallocd = 0; 07199 f.offset = 0; 07200 f.samples = 0; 07201 iax_frame_wrap(fr, &f); 07202 if(f.subclass == IAX_COMMAND_LAGRQ) { 07203 /* Received a LAGRQ - echo back a LAGRP */ 07204 fr->af.subclass = IAX_COMMAND_LAGRP; 07205 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 07206 } else { 07207 /* Received LAGRP in response to our LAGRQ */ 07208 unsigned int ts; 07209 /* This is a reply we've been given, actually measure the difference */ 07210 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 07211 iaxs[fr->callno]->lag = ts - fr->ts; 07212 if (option_debug && iaxdebug) 07213 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", 07214 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 07215 } 07216 break; 07217 case IAX_COMMAND_AUTHREQ: 07218 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07219 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>"); 07220 break; 07221 } 07222 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 07223 ast_log(LOG_WARNING, 07224 "I don't know how to authenticate %s to %s\n", 07225 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 07226 } 07227 break; 07228 case IAX_COMMAND_AUTHREP: 07229 /* For security, always ack immediately */ 07230 if (delayreject) 07231 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07232 /* Ignore once we've started */ 07233 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 07234 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>"); 07235 break; 07236 } 07237 if (authenticate_verify(iaxs[fr->callno], &ies)) { 07238 if (authdebug) 07239 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); 07240 memset(&ied0, 0, sizeof(ied0)); 07241 auth_fail(fr->callno, IAX_COMMAND_REJECT); 07242 break; 07243 } 07244 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 07245 /* This might re-enter the IAX code and need the lock */ 07246 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 07247 } else 07248 exists = 0; 07249 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 07250 if (authdebug) 07251 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); 07252 memset(&ied0, 0, sizeof(ied0)); 07253 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07254 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07255 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07256 } else { 07257 /* Select an appropriate format */ 07258 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07259 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07260 using_prefs = "reqonly"; 07261 } else { 07262 using_prefs = "disabled"; 07263 } 07264 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 07265 memset(&pref, 0, sizeof(pref)); 07266 strcpy(caller_pref_buf, "disabled"); 07267 strcpy(host_pref_buf, "disabled"); 07268 } else { 07269 using_prefs = "mine"; 07270 if (ies.codec_prefs) 07271 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 07272 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07273 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07274 pref = iaxs[fr->callno]->rprefs; 07275 using_prefs = "caller"; 07276 } else { 07277 pref = iaxs[fr->callno]->prefs; 07278 } 07279 } else /* if no codec_prefs IE do it the old way */ 07280 pref = iaxs[fr->callno]->prefs; 07281 07282 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 07283 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 07284 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 07285 } 07286 if (!format) { 07287 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07288 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); 07289 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 07290 } 07291 if (!format) { 07292 if (authdebug) { 07293 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07294 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); 07295 else 07296 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); 07297 } 07298 memset(&ied0, 0, sizeof(ied0)); 07299 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07300 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07301 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07302 } else { 07303 /* Pick one... */ 07304 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07305 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 07306 format = 0; 07307 } else { 07308 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07309 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 07310 memset(&pref, 0, sizeof(pref)); 07311 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 07312 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07313 strcpy(caller_pref_buf,"disabled"); 07314 strcpy(host_pref_buf,"disabled"); 07315 } else { 07316 using_prefs = "mine"; 07317 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07318 /* Do the opposite of what we tried above. */ 07319 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07320 pref = iaxs[fr->callno]->prefs; 07321 } else { 07322 pref = iaxs[fr->callno]->rprefs; 07323 using_prefs = "caller"; 07324 } 07325 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 07326 } else /* if no codec_prefs IE do it the old way */ 07327 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07328 } 07329 } 07330 if (!format) { 07331 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 07332 if (authdebug) { 07333 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07334 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); 07335 else 07336 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); 07337 } 07338 memset(&ied0, 0, sizeof(ied0)); 07339 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07340 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07341 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07342 } 07343 } 07344 } 07345 if (format) { 07346 /* Authentication received */ 07347 memset(&ied1, 0, sizeof(ied1)); 07348 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 07349 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 07350 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 07351 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07352 if (option_verbose > 2) 07353 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" 07354 "%srequested format = %s,\n" 07355 "%srequested prefs = %s,\n" 07356 "%sactual format = %s,\n" 07357 "%shost prefs = %s,\n" 07358 "%spriority = %s\n", 07359 ast_inet_ntoa(sin.sin_addr), 07360 VERBOSE_PREFIX_4, 07361 ast_getformatname(iaxs[fr->callno]->peerformat), 07362 VERBOSE_PREFIX_4, 07363 caller_pref_buf, 07364 VERBOSE_PREFIX_4, 07365 ast_getformatname(format), 07366 VERBOSE_PREFIX_4, 07367 host_pref_buf, 07368 VERBOSE_PREFIX_4, 07369 using_prefs); 07370 07371 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07372 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 07373 iax2_destroy(fr->callno); 07374 } else { 07375 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07376 /* If this is a TBD call, we're ready but now what... */ 07377 if (option_verbose > 2) 07378 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 07379 } 07380 } 07381 } 07382 break; 07383 case IAX_COMMAND_DIAL: 07384 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 07385 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 07386 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 07387 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 07388 if (authdebug) 07389 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); 07390 memset(&ied0, 0, sizeof(ied0)); 07391 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07392 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07393 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07394 } else { 07395 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07396 if (option_verbose > 2) 07397 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat); 07398 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 07399 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 07400 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) 07401 iax2_destroy(fr->callno); 07402 } 07403 } 07404 break; 07405 case IAX_COMMAND_INVAL: 07406 iaxs[fr->callno]->error = ENOTCONN; 07407 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno); 07408 iax2_destroy(fr->callno); 07409 if (option_debug) 07410 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno); 07411 break; 07412 case IAX_COMMAND_VNAK: 07413 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); 07414 /* Force retransmission */ 07415 vnak_retransmit(fr->callno, fr->iseqno); 07416 break; 07417 case IAX_COMMAND_REGREQ: 07418 case IAX_COMMAND_REGREL: 07419 /* For security, always ack immediately */ 07420 if (delayreject) 07421 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07422 if (register_verify(fr->callno, &sin, &ies)) { 07423 /* Send delayed failure */ 07424 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 07425 break; 07426 } 07427 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 07428 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) { 07429 if (f.subclass == IAX_COMMAND_REGREL) 07430 memset(&sin, 0, sizeof(sin)); 07431 if (update_registry(iaxs[fr->callno]->peer, &sin, fr->callno, ies.devicetype, fd, ies.refresh)) 07432 ast_log(LOG_WARNING, "Registry error\n"); 07433 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) 07434 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 07435 break; 07436 } 07437 registry_authrequest(iaxs[fr->callno]->peer, fr->callno); 07438 break; 07439 case IAX_COMMAND_REGACK: 07440 if (iax2_ack_registry(&ies, &sin, fr->callno)) 07441 ast_log(LOG_WARNING, "Registration failure\n"); 07442 /* Send ack immediately, before we destroy */ 07443 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07444 iax2_destroy(fr->callno); 07445 break; 07446 case IAX_COMMAND_REGREJ: 07447 if (iaxs[fr->callno]->reg) { 07448 if (authdebug) { 07449 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)); 07450 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>"); 07451 } 07452 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 07453 } 07454 /* Send ack immediately, before we destroy */ 07455 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07456 iax2_destroy(fr->callno); 07457 break; 07458 case IAX_COMMAND_REGAUTH: 07459 /* Authentication request */ 07460 if (registry_rerequest(&ies, fr->callno, &sin)) { 07461 memset(&ied0, 0, sizeof(ied0)); 07462 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 07463 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 07464 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07465 } 07466 break; 07467 case IAX_COMMAND_TXREJ: 07468 iaxs[fr->callno]->transferring = 0; 07469 if (option_verbose > 2) 07470 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 07471 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 07472 if (iaxs[fr->callno]->bridgecallno) { 07473 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 07474 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 07475 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 07476 } 07477 } 07478 break; 07479 case IAX_COMMAND_TXREADY: 07480 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 07481 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 07482 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 07483 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 07484 else 07485 iaxs[fr->callno]->transferring = TRANSFER_READY; 07486 if (option_verbose > 2) 07487 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 07488 if (iaxs[fr->callno]->bridgecallno) { 07489 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 07490 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 07491 /* They're both ready, now release them. */ 07492 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 07493 if (option_verbose > 2) 07494 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 07495 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 07496 07497 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 07498 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 07499 07500 memset(&ied0, 0, sizeof(ied0)); 07501 memset(&ied1, 0, sizeof(ied1)); 07502 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 07503 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 07504 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 07505 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 07506 } else { 07507 if (option_verbose > 2) 07508 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 07509 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 07510 07511 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 07512 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 07513 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 07514 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 07515 07516 /* Stop doing lag & ping requests */ 07517 stop_stuff(fr->callno); 07518 stop_stuff(iaxs[fr->callno]->bridgecallno); 07519 07520 memset(&ied0, 0, sizeof(ied0)); 07521 memset(&ied1, 0, sizeof(ied1)); 07522 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 07523 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 07524 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 07525 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 07526 } 07527 07528 } 07529 } 07530 } 07531 break; 07532 case IAX_COMMAND_TXREQ: 07533 try_transfer(iaxs[fr->callno], &ies); 07534 break; 07535 case IAX_COMMAND_TXCNT: 07536 if (iaxs[fr->callno]->transferring) 07537 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 07538 break; 07539 case IAX_COMMAND_TXREL: 07540 /* Send ack immediately, rather than waiting until we've changed addresses */ 07541 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07542 complete_transfer(fr->callno, &ies); 07543 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 07544 break; 07545 case IAX_COMMAND_TXMEDIA: 07546 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 07547 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 07548 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 07549 } 07550 break; 07551 case IAX_COMMAND_DPREP: 07552 complete_dpreply(iaxs[fr->callno], &ies); 07553 break; 07554 case IAX_COMMAND_UNSUPPORT: 07555 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 07556 break; 07557 case IAX_COMMAND_FWDOWNL: 07558 /* Firmware download */ 07559 memset(&ied0, 0, sizeof(ied0)); 07560 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 07561 if (res < 0) 07562 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07563 else if (res > 0) 07564 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 07565 else 07566 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 07567 break; 07568 default: 07569 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); 07570 memset(&ied0, 0, sizeof(ied0)); 07571 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 07572 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 07573 } 07574 /* Free remote variables (if any) */ 07575 if (ies.vars) 07576 ast_variables_destroy(ies.vars); 07577 07578 /* Don't actually pass these frames along */ 07579 if ((f.subclass != IAX_COMMAND_ACK) && 07580 (f.subclass != IAX_COMMAND_TXCNT) && 07581 (f.subclass != IAX_COMMAND_TXACC) && 07582 (f.subclass != IAX_COMMAND_INVAL) && 07583 (f.subclass != IAX_COMMAND_VNAK)) { 07584 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 07585 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07586 } 07587 ast_mutex_unlock(&iaxsl[fr->callno]); 07588 return 1; 07589 } 07590 /* Unless this is an ACK or INVAL frame, ack it */ 07591 if (iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 07592 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07593 } else if (minivid) { 07594 f.frametype = AST_FRAME_VIDEO; 07595 if (iaxs[fr->callno]->videoformat > 0) 07596 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 07597 else { 07598 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n "); 07599 iax2_vnak(fr->callno); 07600 ast_mutex_unlock(&iaxsl[fr->callno]); 07601 return 1; 07602 } 07603 f.datalen = res - sizeof(*vh); 07604 if (f.datalen) 07605 f.data = thread->buf + sizeof(*vh); 07606 else 07607 f.data = NULL; 07608 #ifdef IAXTESTS 07609 if (test_resync) { 07610 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 07611 } else 07612 #endif /* IAXTESTS */ 07613 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 07614 } else { 07615 /* A mini frame */ 07616 f.frametype = AST_FRAME_VOICE; 07617 if (iaxs[fr->callno]->voiceformat > 0) 07618 f.subclass = iaxs[fr->callno]->voiceformat; 07619 else { 07620 ast_log(LOG_WARNING, "Received mini frame before first full voice frame\n "); 07621 iax2_vnak(fr->callno); 07622 ast_mutex_unlock(&iaxsl[fr->callno]); 07623 return 1; 07624 } 07625 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 07626 if (f.datalen < 0) { 07627 ast_log(LOG_WARNING, "Datalen < 0?\n"); 07628 ast_mutex_unlock(&iaxsl[fr->callno]); 07629 return 1; 07630 } 07631 if (f.datalen) 07632 f.data = thread->buf + sizeof(*mh); 07633 else 07634 f.data = NULL; 07635 #ifdef IAXTESTS 07636 if (test_resync) { 07637 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 07638 } else 07639 #endif /* IAXTESTS */ 07640 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 07641 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 07642 } 07643 /* Don't pass any packets until we're started */ 07644 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07645 ast_mutex_unlock(&iaxsl[fr->callno]); 07646 return 1; 07647 } 07648 /* Common things */ 07649 f.src = "IAX2"; 07650 f.mallocd = 0; 07651 f.offset = 0; 07652 f.len = 0; 07653 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 07654 f.samples = ast_codec_get_samples(&f); 07655 /* We need to byteswap incoming slinear samples from network byte order */ 07656 if (f.subclass == AST_FORMAT_SLINEAR) 07657 ast_frame_byteswap_be(&f); 07658 } else 07659 f.samples = 0; 07660 iax_frame_wrap(fr, &f); 07661 07662 /* If this is our most recent packet, use it as our basis for timestamping */ 07663 if (iaxs[fr->callno]->last < fr->ts) { 07664 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 07665 fr->outoforder = 0; 07666 } else { 07667 if (option_debug && iaxdebug) 07668 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); 07669 fr->outoforder = -1; 07670 } 07671 duped_fr = iaxfrdup2(fr); 07672 if (duped_fr) { 07673 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 07674 } 07675 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 07676 iaxs[fr->callno]->last = fr->ts; 07677 #if 1 07678 if (option_debug && iaxdebug) 07679 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07680 #endif 07681 } 07682 07683 /* Always run again */ 07684 ast_mutex_unlock(&iaxsl[fr->callno]); 07685 return 1; 07686 }
| static int socket_read | ( | int * | id, | |
| int | fd, | |||
| short | events, | |||
| void * | cbdata | |||
| ) | [static] |
Definition at line 6250 of file chan_iax2.c.
References ast_log(), ast_random(), find_idle_thread(), handle_error(), IAX_IOSTATE_READY, insert_idle_thread(), len, LOG_NOTICE, LOG_WARNING, signal_condition(), t, and thread.
Referenced by network_thread(), peer_set_srcaddr(), and set_config().
06251 { 06252 struct iax2_thread *thread; 06253 socklen_t len; 06254 time_t t; 06255 static time_t last_errtime=0; 06256 06257 thread = find_idle_thread(); 06258 if (thread) { 06259 len = sizeof(thread->iosin); 06260 thread->iofd = fd; 06261 thread->iores = recvfrom(fd, thread->buf, sizeof(thread->buf), 0,(struct sockaddr *) &thread->iosin, &len); 06262 if (thread->iores < 0) { 06263 if (errno != ECONNREFUSED && errno != EAGAIN) 06264 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 06265 handle_error(); 06266 insert_idle_thread(thread); 06267 return 1; 06268 } 06269 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 06270 insert_idle_thread(thread); 06271 return 1; 06272 } 06273 /* Mark as ready and send on its way */ 06274 thread->iostate = IAX_IOSTATE_READY; 06275 #ifdef DEBUG_SCHED_MULTITHREAD 06276 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 06277 #endif 06278 signal_condition(&thread->lock, &thread->cond); 06279 } else { 06280 time(&t); 06281 if (t != last_errtime) 06282 ast_log(LOG_NOTICE, "Out of idle IAX2 threads for I/O, pausing!\n"); 06283 last_errtime = t; 06284 usleep(1); 06285 } 06286 return 1; 06287 }
| static void spawn_dp_lookup | ( | int | callno, | |
| const char * | context, | |||
| const char * | callednum, | |||
| const char * | callerid | |||
| ) | [static] |
Definition at line 6100 of file chan_iax2.c.
References ast_calloc, ast_log(), ast_pthread_create, ast_strdup, dp_lookup_thread(), and LOG_WARNING.
Referenced by socket_process().
06101 { 06102 pthread_t newthread; 06103 struct dpreq_data *dpr; 06104 pthread_attr_t attr; 06105 06106 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 06107 return; 06108 06109 pthread_attr_init(&attr); 06110 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 06111 06112 dpr->callno = callno; 06113 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 06114 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 06115 if (callerid) 06116 dpr->callerid = ast_strdup(callerid); 06117 if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) { 06118 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 06119 } 06120 06121 pthread_attr_destroy(&attr); 06122 }
| static int start_network_thread | ( | void | ) | [static] |
Definition at line 8216 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().
08217 { 08218 pthread_attr_t attr; 08219 int threadcount = 0; 08220 int x; 08221 for (x = 0; x < iaxthreadcount; x++) { 08222 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread)); 08223 if (thread) { 08224 thread->type = IAX_TYPE_POOL; 08225 thread->threadnum = ++threadcount; 08226 ast_mutex_init(&thread->lock); 08227 ast_cond_init(&thread->cond, NULL); 08228 pthread_attr_init(&attr); 08229 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 08230 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 08231 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 08232 free(thread); 08233 thread = NULL; 08234 } 08235 AST_LIST_LOCK(&idle_list); 08236 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 08237 AST_LIST_UNLOCK(&idle_list); 08238 } 08239 } 08240 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL); 08241 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 08242 if (option_verbose > 1) 08243 ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount); 08244 return 0; 08245 }
| static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 5787 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
05788 { 05789 iax2_destroy_helper(iaxs[callno]); 05790 }
| static int timing_read | ( | int * | id, | |
| int | fd, | |||
| short | events, | |||
| void * | cbdata | |||
| ) | [static] |
Definition at line 5975 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_inet_ntoa(), AST_IO_PRI, ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), free, iax2_trunk_expired(), iax2_trunk_peer::lock, LOG_WARNING, MAX_TRUNKDATA, iax2_trunk_peer::next, send_trunk(), tpeers, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.
Referenced by network_thread().
05976 { 05977 char buf[1024]; 05978 int res; 05979 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL; 05980 int processed = 0; 05981 int totalcalls = 0; 05982 #ifdef ZT_TIMERACK 05983 int x = 1; 05984 #endif 05985 struct timeval now; 05986 if (iaxtrunkdebug) 05987 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA); 05988 gettimeofday(&now, NULL); 05989 if (events & AST_IO_PRI) { 05990 #ifdef ZT_TIMERACK 05991 /* Great, this is a timing interface, just call the ioctl */ 05992 if (ioctl(fd, ZT_TIMERACK, &x)) 05993 ast_log(LOG_WARNING, "Unable to acknowledge zap timer\n"); 05994 res = 0; 05995 #endif 05996 } else { 05997 /* Read and ignore from the pseudo channel for timing */ 05998 res = read(fd, buf, sizeof(buf)); 05999 if (res < 1) { 06000 ast_log(LOG_WARNING, "Unable to read from timing fd\n"); 06001 return 1; 06002 } 06003 } 06004 /* For each peer that supports trunking... */ 06005 ast_mutex_lock(&tpeerlock); 06006 tpeer = tpeers; 06007 while(tpeer) { 06008 processed++; 06009 res = 0; 06010 ast_mutex_lock(&tpeer->lock); 06011 /* We can drop a single tpeer per pass. That makes all this logic 06012 substantially easier */ 06013 if (!drop && iax2_trunk_expired(tpeer, &now)) { 06014 /* Take it out of the list, but don't free it yet, because it 06015 could be in use */ 06016 if (prev) 06017 prev->next = tpeer->next; 06018 else 06019 tpeers = tpeer->next; 06020 drop = tpeer; 06021 } else { 06022 res = send_trunk(tpeer, &now); 06023 if (iaxtrunkdebug) 06024 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); 06025 } 06026 totalcalls += res; 06027 res = 0; 06028 ast_mutex_unlock(&tpeer->lock); 06029 prev = tpeer; 06030 tpeer = tpeer->next; 06031 } 06032 ast_mutex_unlock(&tpeerlock); 06033 if (drop) { 06034 ast_mutex_lock(&drop->lock); 06035 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 06036 because by the time they could get tpeerlock, we've already grabbed it */ 06037 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 06038 free(drop->trunkdata); 06039 ast_mutex_unlock(&drop->lock); 06040 ast_mutex_destroy(&drop->lock); 06041 free(drop); 06042 06043 } 06044 if (iaxtrunkdebug) 06045 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 06046 iaxtrunkdebug =0; 06047 return 1; 06048 }
| static int transmit_trunk | ( | struct iax_frame * | f, | |
| struct sockaddr_in * | sin, | |||
| int | sockfd | |||
| ) | [static] |
Definition at line 1640 of file chan_iax2.c.
References ast_log(), f, handle_error(), LOG_DEBUG, and option_debug.
Referenced by send_trunk().
01641 { 01642 int res; 01643 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 01644 sizeof(*sin)); 01645 if (res < 0) { 01646 if (option_debug) 01647 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 01648 handle_error(); 01649 } else 01650 res = 0; 01651 return res; 01652 }
| static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 1339 of file chan_iax2.c.
References ast_calloc, ast_log(), ast_random(), ast_strlen_zero(), MD5Context::buf, ast_iax2_firmware_header::chksum, ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, iax_firmware::dead, ast_iax2_firmware_header::devname, iax_firmware::fd, iax_firmware::fwh, IAX_FIRMWARE_MAGIC, last, len, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), iax_firmware::mmaplen, iax_firmware::next, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl.
Referenced by reload_firmware().
01340 { 01341 struct stat stbuf; 01342 struct iax_firmware *cur; 01343 int ifd; 01344 int fd; 01345 int res; 01346 01347 struct ast_iax2_firmware_header *fwh, fwh2; 01348 struct MD5Context md5; 01349 unsigned char sum[16]; 01350 unsigned char buf[1024]; 01351 int len, chunk; 01352 char *s2; 01353 char *last; 01354 s2 = alloca(strlen(s) + 100); 01355 if (!s2) { 01356 ast_log(LOG_WARNING, "Alloca failed!\n"); 01357 return -1; 01358 } 01359 last = strrchr(s, '/'); 01360 if (last) 01361 last++; 01362 else 01363 last = s; 01364 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 01365 res = stat(s, &stbuf); 01366 if (res < 0) { 01367 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 01368 return -1; 01369 } 01370 /* Make sure it's not a directory */ 01371 if (S_ISDIR(stbuf.st_mode)) 01372 return -1; 01373 ifd = open(s, O_RDONLY); 01374 if (ifd < 0) { 01375 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 01376 return -1; 01377 } 01378 fd = open(s2, O_RDWR | O_CREAT | O_EXCL); 01379 if (fd < 0) { 01380 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 01381 close(ifd); 01382 return -1; 01383 } 01384 /* Unlink our newly created file */ 01385 unlink(s2); 01386 01387 /* Now copy the firmware into it */ 01388 len = stbuf.st_size; 01389 while(len) { 01390 chunk = len; 01391 if (chunk > sizeof(buf)) 01392 chunk = sizeof(buf); 01393 res = read(ifd, buf, chunk); 01394 if (res != chunk) { 01395 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01396 close(ifd); 01397 close(fd); 01398 return -1; 01399 } 01400 res = write(fd, buf, chunk); 01401 if (res != chunk) { 01402 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01403 close(ifd); 01404 close(fd); 01405 return -1; 01406 } 01407 len -= chunk; 01408 } 01409 close(ifd); 01410 /* Return to the beginning */ 01411 lseek(fd, 0, SEEK_SET); 01412 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 01413 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 01414 close(fd); 01415 return -1; 01416 } 01417 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 01418 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 01419 close(fd); 01420 return -1; 01421 } 01422 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 01423 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 01424 close(fd); 01425 return -1; 01426 } 01427 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 01428 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 01429 close(fd); 01430 return -1; 01431 } 01432 fwh = mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 01433 if (fwh == (void *) -1) { 01434 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 01435 close(fd); 01436 return -1; 01437 } 01438 MD5Init(&md5); 01439 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 01440 MD5Final(sum, &md5); 01441 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 01442 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 01443 munmap(fwh, stbuf.st_size); 01444 close(fd); 01445 return -1; 01446 } 01447 cur = waresl.wares; 01448 while(cur) { 01449 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 01450 /* Found a candidate */ 01451 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 01452 /* The version we have on loaded is older, load this one instead */ 01453 break; 01454 /* This version is no newer than what we have. Don't worry about it. 01455 We'll consider it a proper load anyhow though */ 01456 munmap(fwh, stbuf.st_size); 01457 close(fd); 01458 return 0; 01459 } 01460 cur = cur->next; 01461 } 01462 if (!cur) { 01463 /* Allocate a new one and link it */ 01464 if ((cur = ast_calloc(1, sizeof(*cur)))) { 01465 cur->fd = -1; 01466 cur->next = waresl.wares; 01467 waresl.wares = cur; 01468 } 01469 } 01470 if (cur) { 01471 if (cur->fwh) { 01472 munmap(cur->fwh, cur->mmaplen); 01473 } 01474 if (cur->fd > -1) 01475 close(cur->fd); 01476 cur->fwh = fwh; 01477 cur->fd = fd; 01478 cur->mmaplen = stbuf.st_size; 01479 cur->dead = 0; 01480 } 01481 return 0; 01482 }
| static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 5250 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, ies, LOG_WARNING, send_command_transfer(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.
Referenced by socket_process().
05251 { 05252 int newcall = 0; 05253 char newip[256]; 05254 struct iax_ie_data ied; 05255 struct sockaddr_in new; 05256 05257 05258 memset(&ied, 0, sizeof(ied)); 05259 if (ies->apparent_addr) 05260 bcopy(ies->apparent_addr, &new, sizeof(new)); 05261 if (ies->callno) 05262 newcall = ies->callno; 05263 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 05264 ast_log(LOG_WARNING, "Invalid transfer request\n"); 05265 return -1; 05266 } 05267 pvt->transfercallno = newcall; 05268 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 05269 inet_aton(newip, &pvt->transfer.sin_addr); 05270 pvt->transfer.sin_family = AF_INET; 05271 pvt->transferring = TRANSFER_BEGIN; 05272 pvt->transferid = ies->transferid; 05273 if (ies->transferid) 05274 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 05275 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 05276 return 0; 05277 }
| static int uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 989 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), and socket_process().
00990 { 00991 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 00992 if (csub & IAX_FLAG_SC_LOG) { 00993 /* special case for 'compressed' -1 */ 00994 if (csub == 0xff) 00995 return -1; 00996 else 00997 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 00998 } 00999 else 01000 return csub; 01001 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 10129 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), iaxpeer_function, and iaxvar_function.
10130 { 10131 ast_custom_function_unregister(&iaxpeer_function); 10132 ast_custom_function_unregister(&iaxvar_function); 10133 return __unload_module(); 10134 }
| static void unlock_both | ( | unsigned short | callno0, | |
| unsigned short | callno1 | |||
| ) | [static] |
Definition at line 3068 of file chan_iax2.c.
References ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
03069 { 03070 ast_mutex_unlock(&iaxsl[callno1]); 03071 ast_mutex_unlock(&iaxsl[callno0]); 03072 }
| static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2182 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().
02183 { 02184 int x; 02185 02186 if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) { 02187 x = fr->ts - iaxs[fr->callno]->last; 02188 if (x < -50000) { 02189 /* Sudden big jump backwards in timestamp: 02190 What likely happened here is that miniframe timestamp has circled but we haven't 02191 gotten the update from the main packet. We'll just pretend that we did, and 02192 update the timestamp appropriately. */ 02193 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF); 02194 if (option_debug && iaxdebug) 02195 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n"); 02196 } 02197 if (x > 50000) { 02198 /* Sudden apparent big jump forwards in timestamp: 02199 What's likely happened is this is an old miniframe belonging to the previous 02200 top-16-bit timestamp that has turned up out of order. 02201 Adjust the timestamp appropriately. */ 02202 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF); 02203 if (option_debug && iaxdebug) 02204 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n"); 02205 } 02206 } 02207 }
| static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2211 of file chan_iax2.c.
References ast_sched_add(), ast_sched_del(), chan_iax2_pvt::callno, CALLNO_TO_PTR, get_from_jb(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, chan_iax2_pvt::rxcore, sched, and signal_condition().
Referenced by __get_from_jb(), and schedule_delivery().
02212 { 02213 int when; 02214 02215 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 02216 02217 when = jb_next(pvt->jb) - when; 02218 02219 if(pvt->jbid > -1) ast_sched_del(sched, pvt->jbid); 02220 02221 if(when <= 0) { 02222 /* XXX should really just empty until when > 0.. */ 02223 when = 1; 02224 } 02225 02226 pvt->jbid = ast_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno)); 02227 02228 /* Signal scheduler thread */ 02229 signal_condition(&sched_lock, &sched_cond); 02230 }
| static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 1144 of file chan_iax2.c.
References ast_log(), iaxs, LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by find_callno().
01145 { 01146 int max = 1; 01147 int x; 01148 /* XXX Prolly don't need locks here XXX */ 01149 for (x=1;x<TRUNK_CALL_START - 1; x++) { 01150 if (iaxs[x]) 01151 max = x + 1; 01152 } 01153 maxnontrunkcall = max; 01154 if (option_debug && iaxdebug) 01155 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max); 01156 }
| static void update_max_trunk | ( | void | ) | [static] |
Definition at line 1130 of file chan_iax2.c.
References ast_log(), iaxs, LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by iax2_destroy().
01131 { 01132 int max = TRUNK_CALL_START; 01133 int x; 01134 /* XXX Prolly don't need locks here XXX */ 01135 for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) { 01136 if (iaxs[x]) 01137 max = x + 1; 01138 } 01139 maxtrunkcall = max; 01140 if (option_debug && iaxdebug) 01141 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max); 01142 }
| static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 1822 of file chan_iax2.c.
References ast_iax2_full_hdr::dcallno, f, IAX_FLAG_RETRANS, iaxs, ast_iax2_full_hdr::iseqno, and chan_iax2_pvt::iseqno.
Referenced by __attempt_transmit().
01823 { 01824 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 01825 struct ast_iax2_full_hdr *fh = f->data; 01826 /* Mark this as a retransmission */ 01827 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 01828 /* Update iseqno */ 01829 f->iseqno = iaxs[f->callno]->iseqno; 01830 fh->iseqno = f->iseqno; 01831 return 0; 01832 }
| static int update_registry | ( | const char * | name, | |
| struct sockaddr_in * | sin, | |||
| int | callno, | |||
| char * | devtype, | |||
| int | fd, | |||
| unsigned short | refresh | |||
| ) | [static] |
Definition at line 5607 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_sched_add(), ast_sched_del(), ast_strlen_zero(), ast_test_flag, ast_verbose(), destroy_peer(), EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), globalflags, iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax_check_version(), IAX_COMMAND_REGACK, IAX_HASCALLERID, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_DATETIME, IAX_IE_FIRMWAREVER, IAX_IE_MSGCOUNT, IAX_IE_REFRESH, IAX_IE_USERNAME, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, iaxs, inaddrcmp(), LOG_NOTICE, LOG_WARNING, manager_event(), option_verbose, realtime_update_peer(), register_peer_exten(), sched, send_command_final(), iax2_peer::sockfd, and VERBOSE_PREFIX_3.
Referenced by socket_process().
05608 { 05609 /* Called from IAX thread only, with proper iaxsl lock */ 05610 struct iax_ie_data ied; 05611 struct iax2_peer *p; 05612 int msgcount; 05613 char data[80]; 05614 int version; 05615 05616 memset(&ied, 0, sizeof(ied)); 05617 05618 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 05619 if (!(p = find_peer(name, 1))) { 05620 ast_log(LOG_WARNING, "No such peer '%s'\n", name); 05621 return -1; 05622 } 05623 05624 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 05625 if (sin->sin_addr.s_addr) { 05626 time_t nowtime; 05627 time(&nowtime); 05628 realtime_update_peer(name, sin, nowtime); 05629 } else { 05630 realtime_update_peer(name, sin, 0); 05631 } 05632 } 05633 if (inaddrcmp(&p->addr, sin)) { 05634 if (iax2_regfunk) 05635 iax2_regfunk(p->name, 1); 05636 /* Stash the IP address from which they registered */ 05637 memcpy(&p->addr, sin, sizeof(p->addr)); 05638 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 05639 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 05640 ast_db_put("IAX/Registry", p->name, data); 05641 if (option_verbose > 2) 05642 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 05643 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 05644 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 05645 register_peer_exten(p, 1); 05646 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05647 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 05648 if (option_verbose > 2) 05649 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 05650 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 05651 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 05652 register_peer_exten(p, 0); 05653 ast_db_del("IAX/Registry", p->name); 05654 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05655 } 05656 /* Update the host */ 05657 /* Verify that the host is really there */ 05658 iax2_poke_peer(p, callno); 05659 } 05660 05661 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 05662 if (!iaxs[callno]) 05663 return 0; 05664 05665 /* Store socket fd */ 05666 p->sockfd = fd; 05667 /* Setup the expiry */ 05668 if (p->expire > -1) 05669 ast_sched_del(sched, p->expire); 05670 /* treat an unspecified refresh interval as the minimum */ 05671 if (!refresh) 05672 refresh = min_reg_expire; 05673 if (refresh > max_reg_expire) { 05674 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 05675 p->name, max_reg_expire, refresh); 05676 p->expiry = max_reg_expire; 05677 } else if (refresh < min_reg_expire) { 05678 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 05679 p->name, min_reg_expire, refresh); 05680 p->expiry = min_reg_expire; 05681 } else { 05682 p->expiry = refresh; 05683 } 05684 if (p->expiry && sin->sin_addr.s_addr) 05685 p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p->name); 05686 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 05687 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 05688 if (sin->sin_addr.s_addr) { 05689 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 05690 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 05691 if (!ast_strlen_zero(p->mailbox)) { 05692 int new, old; 05693 ast_app_inboxcount(p->mailbox, &new, &old); 05694 if (new > 255) 05695 new = 255; 05696 if (old > 255) 05697 old = 255; 05698 msgcount = (old << 8) | new; 05699 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 05700 } 05701 if (ast_test_flag(p, IAX_HASCALLERID)) { 05702 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 05703 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 05704 } 05705 } 05706 version = iax_check_version(devtype); 05707 if (version) 05708 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 05709 if (ast_test_flag(p, IAX_TEMPONLY)) 05710 destroy_peer(p); 05711 return send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 05712 }
| static void vnak_retransmit | ( | int | callno, | |
| int | last | |||
| ) | [static] |
Definition at line 5892 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, f, iaxq, iaxs, and send_packet().
Referenced by socket_process().
05893 { 05894 struct iax_frame *f; 05895 05896 AST_LIST_LOCK(&iaxq.queue); 05897 AST_LIST_TRAVERSE(&iaxq.queue, f, list) { 05898 /* Send a copy immediately */ 05899 if ((f->callno == callno) && iaxs[f->callno] && 05900 (f->oseqno >= last)) { 05901 send_packet(f); 05902 } 05903 } 05904 AST_LIST_UNLOCK(&iaxq.queue); 05905 }
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 218 of file chan_iax2.c.
Referenced by __oh323_new(), ast_cdr_setaccount(), begin_dial(), build_device(), build_gateway(), check_user_full(), disa_exec(), features_call(), gtalk_new(), local_call(), mgcp_new(), rpt_call(), sip_new(), skinny_new(), tds_log(), wait_for_answer(), and zt_new().
int adsi = 0 [static] |
int amaflags = 0 [static] |
Definition at line 221 of file chan_iax2.c.
Referenced by build_device(), build_gateway(), and pgsql_log().
int authdebug = 1 [static] |
int autokill = 0 [static] |
Definition at line 159 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 9933 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 9938 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 9948 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 9943 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 9928 of file chan_iax2.c.
char context[80] = "default" [static] |
Definition at line 143 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 9902 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 9894 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 9886 of file chan_iax2.c.
int defaultsockfd = -1 [static] |
Definition at line 175 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 223 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 273 of file chan_iax2.c.
struct ast_flags globalflags = { 0 } [static] |
Definition at line 226 of file chan_iax2.c.
Referenced by __expire_registry(), aji_create_client(), aji_load_config(), build_peer(), build_user(), find_callno(), find_or_create(), find_user(), find_user_realtime(), forward_message(), iax2_request(), iax2_trunk_queue(), load_config(), make_email_file(), notify_new_message(), populate_defaults(), realtime_peer(), realtime_user(), reload_config(), send_trunk(), sendmail(), set_config(), update_registry(), and vm_execmain().
int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static] |
Definition at line 204 of file chan_iax2.c.
int iax2_encryption = 0 [static] |
Definition at line 224 of file chan_iax2.c.
| enum { ... } iax2_flags |
| int(*) iax2_regfunk(const char *username, int onoff) = NULL |
Definition at line 177 of file chan_iax2.c.
Referenced by __expire_registry(), reg_source_db(), and update_registry().
char iax2_reload_usage[] [static] |
Initial value:
"Usage: iax2 reload\n" " Reloads IAX configuration from iax.conf\n"
Definition at line 9844 of file chan_iax2.c.
| enum { ... } iax2_state |
struct ast_switch iax2_switch [static] |
struct ast_channel_tech iax2_tech [static] |
Definition at line 804 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 9910 of file chan_iax2.c.
int iaxactivethreadcount = 0 [static] |
Definition at line 451 of file chan_iax2.c.
Referenced by __unload_module(), iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 160 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 206 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 162 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 164 of file chan_iax2.c.
int iaxdynamicthreadcount = 0 [static] |
Definition at line 450 of file chan_iax2.c.
Referenced by find_idle_thread(), and iax2_process_thread().
int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static] |
struct ast_iax2_queue iaxq [static] |
struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS] [static] |
Definition at line 767 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(), 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_frame(), 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_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 768 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_fail(), auth_reject(), auto_hangup(), cache_get_callno_locked(), delete_users(), destroy_peer(), 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_frame(), iax2_request(), iax2_show_channels(), iax2_write(), load_module(), lock_both(), make_trunk(), network_thread(), send_command_locked(), socket_process(), and unlock_both().
int iaxthreadcount = DEFAULT_THREAD_COUNT [static] |
Definition at line 448 of file chan_iax2.c.
Referenced by iax2_show_threads(), set_config(), and start_network_thread().
int iaxtrunkdebug = 0 [static] |
Definition at line 208 of file chan_iax2.c.
struct ast_custom_function iaxvar_function [static] |
struct io_context* io [static] |
Definition at line 201 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 151 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 145 of file chan_iax2.c.
struct timeval lastused[IAX_MAX_CALLS] [static] |
Definition at line 769 of file chan_iax2.c.
int max_reg_expire [static] |
Definition at line 169 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 149 of file chan_iax2.c.
int maxauthreq = 3 [static] |
Definition at line 148 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 154 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 156 of file chan_iax2.c.
int maxnontrunkcall = 1 [static] |
Definition at line 153 of file chan_iax2.c.
int maxtrunkcall = TRUNK_CALL_START [static] |
Definition at line 152 of file chan_iax2.c.
int min_reg_expire [static] |
Definition at line 168 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 219 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 220 of file chan_iax2.c.
Referenced by build_device(), check_user_full(), create_addr_from_peer(), and sip_alloc().
struct ast_netsock_list* netsock [static] |
Definition at line 173 of file chan_iax2.c.
Referenced by __unload_module(), ast_netsock_destroy(), load_module(), peer_set_srcaddr(), and set_config().
pthread_t netthreadid = AST_PTHREADT_NULL [static] |
char no_debug_jb_usage[] [static] |
Initial value:
"Usage: iax2 set debug jb off\n" " Disables jitterbuffer debugging information\n"
Definition at line 9906 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 9898 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 9890 of file chan_iax2.c.
struct ast_netsock_list* outsock [static] |
used if sourceaddress specified and bindaddr == INADDR_ANY
Definition at line 174 of file chan_iax2.c.
Referenced by __unload_module(), load_module(), peer_set_srcaddr(), and set_config().
char* papp = "IAX2Provision" [static] |
Definition at line 7890 of file chan_iax2.c.
char* pdescrip [static] |
Initial value:
" IAX2Provision([template]): Provisions the calling IAXy (assuming\n" "the calling entity is in fact an IAXy) with the given template or\n" "default if one is not specified. Returns -1 on error or 0 on success.\n"
Definition at line 7892 of file chan_iax2.c.
int ping_time = 20 [static] |
Definition at line 150 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 139 of file chan_iax2.c.
Referenced by ast_best_codec(), ast_rtp_codec_setpref(), build_peer(), build_user(), check_access(), create_addr(), gtalk_create_member(), gtalk_load_config(), set_config(), set_local_capabilities(), and set_peer_capabilities().
char prune_realtime_usage[] [static] |
Initial value:
"Usage: iax2 prune realtime [<peername>|all]\n" " Prunes object(s) from the cache\n"
Definition at line 9840 of file chan_iax2.c.
char* psyn = "Provision a calling IAXy with a given template" [static] |
Definition at line 7891 of file chan_iax2.c.
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 146 of file chan_iax2.c.
int resyncthreshold = 1000 [static] |
Definition at line 155 of file chan_iax2.c.
struct sched_context* sched [static] |
Definition at line 202 of file chan_iax2.c.
ast_cond_t sched_cond [static] |
Definition at line 231 of file chan_iax2.c.
pthread_t schedthreadid = AST_PTHREADT_NULL [static] |
Definition at line 229 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 9832 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 9860 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 9878 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 9864 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 9836 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 9872 of file chan_iax2.c.
char show_prov_usage[] [static] |
Definition at line 9848 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 9882 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 9828 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 9868 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 9855 of file chan_iax2.c.
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 141 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 210 of file chan_iax2.c.
int timingfd = -1 [static] |
Definition at line 171 of file chan_iax2.c.
unsigned int tos = 0 [static] |
Definition at line 166 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 157 of file chan_iax2.c.
struct ast_firmware_list waresl [static] |
Referenced by __unload_module(), iax2_show_firmware(), iax_check_version(), iax_firmware_append(), load_module(), reload_firmware(), and try_firmware().
1.5.1