#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#include <netinet/ip.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <zlib.h>
#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/options.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/frame.h"
#include "asterisk/cli.h"
#include "asterisk/lock.h"
#include "asterisk/md5.h"
#include "asterisk/dundi.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/utils.h"
#include "asterisk/crypto.h"
#include "asterisk/astdb.h"
#include "asterisk/acl.h"
#include "asterisk/aes.h"
#include "dundi-parser.h"
Go to the source code of this file.
Data Structures | |
struct | dundi_hint_metadata |
struct | dundi_mapping |
struct | dundi_packet |
struct | dundi_peer |
struct | dundi_precache_queue |
struct | dundi_query_state |
struct | dundi_request |
struct | dundi_transaction |
struct | permission |
Defines | |
#define | DUNDI_FLAG_INTERNAL_NOPARTIAL (1 << 17) |
#define | DUNDI_MODEL_INBOUND (1 << 0) |
#define | DUNDI_MODEL_OUTBOUND (1 << 1) |
#define | DUNDI_MODEL_SYMMETRIC (DUNDI_MODEL_INBOUND | DUNDI_MODEL_OUTBOUND) |
#define | DUNDI_SECRET_TIME DUNDI_DEFAULT_CACHE_TIME |
#define | DUNDI_TIMING_HISTORY 10 |
#define | FLAG_DEAD (1 << 1) |
#define | FLAG_ENCRYPT (1 << 4) |
#define | FLAG_FINAL (1 << 2) |
#define | FLAG_ISQUAL (1 << 3) |
#define | FLAG_ISREG (1 << 0) |
#define | FLAG_SENDFULLKEY (1 << 5) |
#define | FLAG_STOREHIST (1 << 6) |
#define | FORMAT "%-12.12s %-12.12s %02d:%02d:%02d\n" |
#define | FORMAT "%-12.12s %-7d %-12.12s %-10.10s %-5.5s %-25.25s\n" |
#define | FORMAT "%-15s %-15s %-15s %-3.3d %-3.3d\n" |
#define | FORMAT "%-16.16s:%5d %-5.5d %-5.5d %-3.3d %-3.3d %-3.3d\n" |
#define | FORMAT "%-20.20s %-15.15s %s %-10.10s %-8.8s %-15.15s\n" |
#define | FORMAT2 "%-12.12s %-12.12s %-10.10s\n" |
#define | FORMAT2 "%-12.12s %-7.7s %-12.12s %-10.10s %-5.5s %-25.25s\n" |
#define | FORMAT2 "%-15s %-15s %-15s %-3.3s %-3.3s\n" |
#define | FORMAT2 "%-22.22s %-5.5s %-5.5s %-3.3s %-3.3s %-3.3s\n" |
#define | FORMAT2 "%-20.20s %-15.15s %-10.10s %-8.8s %-15.15s\n" |
#define | KEY_IN 1 |
#define | KEY_OUT 0 |
#define | MAX_OPTS 128 |
#define | MAX_PACKET_SIZE 8192 |
#define | MAX_RESULTS 64 |
Functions | |
static void | abort_request (struct dundi_request *dr) |
static int | ack_trans (struct dundi_transaction *trans, int iseqno) |
static struct permission * | append_permission (struct permission *p, char *s, int allow) |
static int | append_transaction (struct dundi_request *dr, struct dundi_peer *p, int ttl, dundi_eid *avoid[]) |
static void | apply_peer (struct dundi_transaction *trans, struct dundi_peer *p) |
AST_MUTEX_DEFINE_STATIC (pclock) | |
AST_MUTEX_DEFINE_STATIC (peerlock) | |
static unsigned long | avoid_crc32 (dundi_eid *avoid[]) |
static void | build_iv (unsigned char *iv) |
static void | build_mapping (char *name, char *value) |
static void | build_peer (dundi_eid *eid, struct ast_variable *v, int *globalpcmode) |
static void | build_secret (char *secret, int seclen) |
static void | build_transactions (struct dundi_request *dr, int ttl, int order, int *foundcache, int *skipped, int blockempty, int nocache, int modeselect, dundi_eid *skip, dundi_eid *avoid[], int directs[]) |
static int | cache_lookup (struct dundi_request *req, dundi_eid *peer_eid, unsigned long crc32, int *lowexpiration) |
static int | cache_lookup_internal (time_t now, struct dundi_request *req, char *key, char *eid_str_full, int *lowexpiration) |
static int | cache_save (dundi_eid *eidpeer, struct dundi_request *req, int start, int unaffected, int expiration, int push) |
static int | cache_save_hint (dundi_eid *eidpeer, struct dundi_request *req, struct dundi_hint *hint, int expiration) |
static void | cancel_request (struct dundi_request *dr) |
static int | check_key (struct dundi_peer *peer, unsigned char *newkey, unsigned char *newsig, unsigned long keycrc32) |
static void | check_password (void) |
static int | check_request (struct dundi_request *dr) |
static char * | complete_peer_4 (char *line, char *word, int pos, int state) |
static char * | complete_peer_helper (char *line, char *word, int pos, int state, int rpos) |
static struct dundi_transaction * | create_transaction (struct dundi_peer *p) |
static int | decrypt_memcpy (unsigned char *dst, unsigned char *src, int len, unsigned char *iv, aes_decrypt_ctx *dcx) |
char * | description (void) |
Provides a description of the module. | |
static void | destroy_map (struct dundi_mapping *map) |
static void | destroy_packet (struct dundi_packet *pack, int needfree) |
static void | destroy_packets (struct dundi_packet *p) |
static void | destroy_peer (struct dundi_peer *peer) |
static void | destroy_permissions (struct permission *p) |
static void | destroy_trans (struct dundi_transaction *trans, int fromtimeout) |
static int | discover_transactions (struct dundi_request *dr) |
static int | do_autokill (void *data) |
static int | do_qualify (void *data) |
static int | do_register (void *data) |
static int | do_register_expire (void *data) |
static int | dundi_ack (struct dundi_transaction *trans, int final) |
static int | dundi_answer_entity (struct dundi_transaction *trans, struct dundi_ies *ies, char *ccontext) |
static int | dundi_answer_query (struct dundi_transaction *trans, struct dundi_ies *ies, char *ccontext) |
static int | dundi_canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
static void | dundi_debug_output (const char *data) |
static struct dundi_hdr * | dundi_decrypt (struct dundi_transaction *trans, unsigned char *dst, int *dstlen, struct dundi_hdr *ohdr, struct dundi_encblock *src, int srclen) |
static int | dundi_discover (struct dundi_transaction *trans) |
static int | dundi_do_debug (int fd, int argc, char *argv[]) |
static int | dundi_do_lookup (int fd, int argc, char *argv[]) |
static int | dundi_do_precache (int fd, int argc, char *argv[]) |
static int | dundi_do_query (int fd, int argc, char *argv[]) |
static int | dundi_do_store_history (int fd, int argc, char *argv[]) |
static int | dundi_encrypt (struct dundi_transaction *trans, struct dundi_packet *pack) |
static void | dundi_error_output (const char *data) |
static int | dundi_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, int newstack, const char *data) |
static int | dundi_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
static int | dundi_flush (int fd, int argc, char *argv[]) |
static int | dundi_helper (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *data, int flag) |
static void | dundi_ie_append_eid_appropriately (struct dundi_ie_data *ied, char *context, dundi_eid *eid, dundi_eid *us) |
int | dundi_lookup (struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number, int cbypass) |
Lookup the given number in the given dundi context (or e164 if unspecified) using the given callerid (if specified) and return up to maxret results in the array specified. returns the number of results found or -1 on a hangup of teh channel. | |
static int | dundi_lookup_exec (struct ast_channel *chan, void *data) |
static int | dundi_lookup_internal (struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number, int ttl, int blockempty, struct dundi_hint_metadata *md, int *expiration, int cybpass, int modeselect, dundi_eid *skip, dundi_eid *avoid[], int direct[]) |
static int | dundi_lookup_local (struct dundi_result *dr, struct dundi_mapping *map, char *called_number, dundi_eid *us_eid, int anscnt, struct dundi_hint_metadata *hmd) |
static void * | dundi_lookup_thread (void *data) |
static int | dundi_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
static int | dundi_no_debug (int fd, int argc, char *argv[]) |
static int | dundi_no_store_history (int fd, int argc, char *argv[]) |
int | dundi_precache (const char *context, const char *number) |
Pre-cache to push upstream peers. | |
static void | dundi_precache_full (void) |
static int | dundi_precache_internal (const char *context, const char *number, int ttl, dundi_eid *avoids[]) |
static void * | dundi_precache_thread (void *data) |
static int | dundi_prop_precache (struct dundi_transaction *trans, struct dundi_ies *ies, char *ccontext) |
static int | dundi_query (struct dundi_transaction *trans) |
int | dundi_query_eid (struct dundi_entity_info *dei, const char *dcontext, dundi_eid eid) |
Retrieve information on a specific EID. | |
static int | dundi_query_eid_internal (struct dundi_entity_info *dei, const char *dcontext, dundi_eid *eid, struct dundi_hint_metadata *hmd, int ttl, int blockempty, dundi_eid *avoid[]) |
static void * | dundi_query_thread (void *data) |
static void | dundi_reject (struct dundi_hdr *h, struct sockaddr_in *sin) |
static int | dundi_rexmit (void *data) |
static int | dundi_send (struct dundi_transaction *trans, int cmdresp, int flags, int final, struct dundi_ie_data *ied) |
static int | dundi_show_entityid (int fd, int argc, char *argv[]) |
static int | dundi_show_mappings (int fd, int argc, char *argv[]) |
static int | dundi_show_peer (int fd, int argc, char *argv[]) |
static int | dundi_show_peers (int fd, int argc, char *argv[]) |
static int | dundi_show_precache (int fd, int argc, char *argv[]) |
static int | dundi_show_requests (int fd, int argc, char *argv[]) |
static int | dundi_show_trans (int fd, int argc, char *argv[]) |
static int | dundi_xmit (struct dundi_packet *pack) |
static char * | dundifunc_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
static int | encrypt_memcpy (unsigned char *dst, unsigned char *src, int len, unsigned char *iv, aes_encrypt_ctx *ecx) |
static struct dundi_peer * | find_peer (dundi_eid *eid) |
static struct dundi_transaction * | find_transaction (struct dundi_hdr *hdr, struct sockaddr_in *sin) |
static int | get_trans_id (void) |
static int | handle_command_response (struct dundi_transaction *trans, struct dundi_hdr *hdr, int datalen, int encrypted) |
static int | handle_frame (struct dundi_hdr *h, struct sockaddr_in *sin, int datalen) |
static int | has_permission (struct permission *ps, char *cont) |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module (void) |
Initialize the module. | |
static void | load_password (void) |
static void | mark_mappings (void) |
static void | mark_peers (void) |
static char * | model2str (int model) |
static void * | network_thread (void *ignore) |
static int | optimize_transactions (struct dundi_request *dr, int order) |
static void | populate_addr (struct dundi_peer *peer, dundi_eid *eid) |
static int | precache_trans (struct dundi_transaction *trans, struct dundi_mapping *maps, int mapcount, int *minexp, int *foundanswers) |
static int | precache_transactions (struct dundi_request *dr, struct dundi_mapping *maps, int mapcount, int *expiration, int *foundanswers) |
static void * | process_precache (void *ign) |
static void | prune_mappings (void) |
static void | prune_peers (void) |
static void | qualify_peer (struct dundi_peer *peer, int schedonly) |
static int | query_transactions (struct dundi_request *dr) |
static int | register_request (struct dundi_request *dr, struct dundi_request **pending) |
int | reload (void) |
Reload stuff. | |
static void | reschedule_precache (const char *number, const char *context, int expiration) |
static int | rescomp (const void *a, const void *b) |
static void | reset_global_eid (void) |
static int | reset_transaction (struct dundi_transaction *trans) |
static void | save_secret (const char *newkey, const char *oldkey) |
static int | set_config (char *config_file, struct sockaddr_in *sin) |
static int | socket_read (int *id, int fd, short events, void *cbdata) |
static void | sort_results (struct dundi_result *results, int count) |
static int | start_network_thread (void) |
static int | str2tech (char *str) |
static char * | tech2str (int tech) |
int | unload_module (void) |
Cleanup all module structures, sockets, etc. | |
static void | unregister_request (struct dundi_request *dr) |
static int | update_key (struct dundi_peer *peer) |
int | usecount (void) |
Provides a usecount. | |
Variables | |
dundi_transaction * | alltrans |
static char * | app = "DUNDiLookup" |
char | ast_config_AST_KEY_DIR [] |
static int | authdebug = 0 |
static struct ast_cli_entry | cli_debug |
static struct ast_cli_entry | cli_flush |
static struct ast_cli_entry | cli_lookup |
static struct ast_cli_entry | cli_no_debug |
static struct ast_cli_entry | cli_no_store_history |
static struct ast_cli_entry | cli_precache |
static struct ast_cli_entry | cli_queryeid |
static struct ast_cli_entry | cli_show_entityid |
static struct ast_cli_entry | cli_show_mappings |
static struct ast_cli_entry | cli_show_peer |
static struct ast_cli_entry | cli_show_peers |
static struct ast_cli_entry | cli_show_precache |
static struct ast_cli_entry | cli_show_requests |
static struct ast_cli_entry | cli_show_trans |
static struct ast_cli_entry | cli_store_history |
static char | country [80] |
static char | cursecret [80] |
static char | debug_usage [] |
static int | default_expiration = 60 |
static char | dept [80] |
static char * | descrip |
static int | dundi_cache_time = DUNDI_DEFAULT_CACHE_TIME |
static struct ast_custom_function | dundi_function |
static int | dundi_key_ttl = DUNDI_DEFAULT_KEY_EXPIRE |
static struct ast_switch | dundi_switch |
static int | dundi_ttl = DUNDI_DEFAULT_TTL |
static int | dundidebug = 0 |
static char | email [80] |
static dundi_eid | empty_eid = { { 0, 0, 0, 0, 0, 0 } } |
static char | flush_usage [] |
static int | global_autokilltimeout = 0 |
static dundi_eid | global_eid |
static int | global_storehistory = 0 |
static struct io_context * | io |
static char | ipaddr [80] |
LOCAL_USER_DECL | |
static char | locality [80] |
static char | lookup_usage [] |
static struct dundi_mapping * | mappings |
static int | netsocket = -1 |
static pthread_t | netthreadid = AST_PTHREADT_NULL |
static char | no_debug_usage [] |
static char | no_store_history_usage [] |
static char | org [80] |
static struct dundi_precache_queue * | pcq |
static struct dundi_peer * | peers |
static char | phone [80] |
static char | precache_usage [] |
static pthread_t | precachethreadid = AST_PTHREADT_NULL |
static char | query_usage [] |
dundi_request * | requests |
static time_t | rotatetime |
static struct sched_context * | sched |
static char | secretpath [80] |
static char | show_entityid_usage [] |
static char | show_mappings_usage [] |
static char | show_peer_usage [] |
static char | show_peers_usage [] |
static char | show_precache_usage [] |
static char | show_requests_usage [] |
static char | show_trans_usage [] |
STANDARD_LOCAL_USER | |
static char | stateprov [80] |
static char | store_history_usage [] |
static char * | synopsis = "Look up a number with DUNDi" |
static char * | tdesc = "Distributed Universal Number Discovery (DUNDi)" |
static int | tos = 0 |
Definition in file pbx_dundi.c.
#define DUNDI_FLAG_INTERNAL_NOPARTIAL (1 << 17) |
Definition at line 111 of file pbx_dundi.c.
Referenced by build_mapping(), and dundi_lookup_local().
#define DUNDI_MODEL_INBOUND (1 << 0) |
Definition at line 96 of file pbx_dundi.c.
Referenced by build_peer(), dundi_show_peer(), handle_command_response(), and model2str().
#define DUNDI_MODEL_OUTBOUND (1 << 1) |
Definition at line 97 of file pbx_dundi.c.
Referenced by build_peer(), build_transactions(), dundi_show_peer(), model2str(), and set_config().
#define DUNDI_MODEL_SYMMETRIC (DUNDI_MODEL_INBOUND | DUNDI_MODEL_OUTBOUND) |
#define DUNDI_SECRET_TIME DUNDI_DEFAULT_CACHE_TIME |
#define DUNDI_TIMING_HISTORY 10 |
Definition at line 101 of file pbx_dundi.c.
Referenced by destroy_trans(), dundi_flush(), and dundi_show_peer().
#define FLAG_DEAD (1 << 1) |
Definition at line 104 of file pbx_dundi.c.
Referenced by dundi_lookup_thread(), dundi_precache_thread(), dundi_query_thread(), and precache_transactions().
#define FLAG_ENCRYPT (1 << 4) |
Definition at line 107 of file pbx_dundi.c.
Referenced by apply_peer(), dundi_send(), and handle_command_response().
#define FLAG_FINAL (1 << 2) |
Definition at line 105 of file pbx_dundi.c.
Referenced by dundi_send(), handle_frame(), and reset_transaction().
#define FLAG_ISQUAL (1 << 3) |
Definition at line 106 of file pbx_dundi.c.
Referenced by destroy_trans(), dundi_rexmit(), and qualify_peer().
#define FLAG_ISREG (1 << 0) |
#define FLAG_SENDFULLKEY (1 << 5) |
Definition at line 108 of file pbx_dundi.c.
Referenced by create_transaction(), and dundi_encrypt().
#define FLAG_STOREHIST (1 << 6) |
Definition at line 109 of file pbx_dundi.c.
Referenced by create_transaction(), and destroy_trans().
#define FORMAT "%-12.12s %-12.12s %02d:%02d:%02d\n" |
#define FORMAT "%-12.12s %-7d %-12.12s %-10.10s %-5.5s %-25.25s\n" |
#define FORMAT "%-15s %-15s %-15s %-3.3d %-3.3d\n" |
#define FORMAT "%-16.16s:%5d %-5.5d %-5.5d %-3.3d %-3.3d %-3.3d\n" |
#define FORMAT "%-20.20s %-15.15s %s %-10.10s %-8.8s %-15.15s\n" |
#define FORMAT2 "%-12.12s %-12.12s %-10.10s\n" |
#define FORMAT2 "%-12.12s %-7.7s %-12.12s %-10.10s %-5.5s %-25.25s\n" |
#define FORMAT2 "%-15s %-15s %-15s %-3.3s %-3.3s\n" |
#define FORMAT2 "%-22.22s %-5.5s %-5.5s %-3.3s %-3.3s %-3.3s\n" |
#define FORMAT2 "%-20.20s %-15.15s %-10.10s %-8.8s %-15.15s\n" |
#define KEY_IN 1 |
Definition at line 120 of file pbx_dundi.c.
#define KEY_OUT 0 |
Definition at line 119 of file pbx_dundi.c.
#define MAX_OPTS 128 |
#define MAX_PACKET_SIZE 8192 |
#define MAX_RESULTS 64 |
Definition at line 74 of file pbx_dundi.c.
Referenced by dundi_do_lookup(), dundi_exec(), dundi_helper(), dundi_lookup_exec(), dundi_lookup_thread(), dundi_precache_internal(), dundi_prop_precache(), dundifunc_read(), and precache_trans().
static void abort_request | ( | struct dundi_request * | dr | ) | [static] |
Definition at line 3380 of file pbx_dundi.c.
References ast_mutex_lock(), ast_mutex_unlock(), destroy_trans(), and dr.
Referenced by dundi_lookup_internal().
03381 { 03382 ast_mutex_lock(&peerlock); 03383 while(dr->trans) 03384 destroy_trans(dr->trans, 0); 03385 ast_mutex_unlock(&peerlock); 03386 }
static int ack_trans | ( | struct dundi_transaction * | trans, | |
int | iseqno | |||
) | [static] |
Definition at line 1918 of file pbx_dundi.c.
References ast_log(), ast_sched_del(), dundi_transaction::autokillid, destroy_packet(), destroy_packets(), dundi_packet::h, dundi_transaction::lasttrans, LOG_WARNING, dundi_packet::next, dundi_hdr::oseqno, and dundi_transaction::packets.
Referenced by handle_frame().
01919 { 01920 /* Ack transmitted packet corresponding to iseqno */ 01921 struct dundi_packet *pack; 01922 pack = trans->packets; 01923 while(pack) { 01924 if ((pack->h->oseqno + 1) % 255 == iseqno) { 01925 destroy_packet(pack, 0); 01926 if (trans->lasttrans) { 01927 ast_log(LOG_WARNING, "Whoa, there was still a last trans?\n"); 01928 destroy_packets(trans->lasttrans); 01929 } 01930 trans->lasttrans = pack; 01931 if (trans->autokillid > -1) 01932 ast_sched_del(sched, trans->autokillid); 01933 trans->autokillid = -1; 01934 return 1; 01935 } 01936 pack = pack->next; 01937 } 01938 return 0; 01939 }
static struct permission* append_permission | ( | struct permission * | p, | |
char * | s, | |||
int | allow | |||
) | [static] |
Definition at line 4096 of file pbx_dundi.c.
References malloc, and permission::next.
Referenced by build_peer().
04097 { 04098 struct permission *start; 04099 start = p; 04100 if (p) { 04101 while(p->next) 04102 p = p->next; 04103 } 04104 if (p) { 04105 p->next = malloc(sizeof(struct permission) + strlen(s) + 1); 04106 p = p->next; 04107 } else { 04108 p = malloc(sizeof(struct permission) + strlen(s) + 1); 04109 } 04110 if (p) { 04111 memset(p, 0, sizeof(struct permission)); 04112 memcpy(p->name, s, strlen(s) + 1); 04113 p->allow = allow; 04114 } 04115 return start ? start : p; 04116 }
static int append_transaction | ( | struct dundi_request * | dr, | |
struct dundi_peer * | p, | |||
int | ttl, | |||
dundi_eid * | avoid[] | |||
) | [static] |
Definition at line 3333 of file pbx_dundi.c.
References dundi_peer::addr, ast_log(), ast_strlen_zero(), create_transaction(), dr, dundi_eid_to_str(), DUNDI_MAX_STACK, dundi_peer::eid, dundi_transaction::eidcount, dundi_transaction::eids, dundi_peer::lastms, LOG_DEBUG, dundi_peer::maxms, dundi_transaction::next, dundi_transaction::parent, and dundi_transaction::ttl.
Referenced by build_transactions().
03334 { 03335 struct dundi_transaction *trans; 03336 int x; 03337 char eid_str[20]; 03338 char eid_str2[20]; 03339 /* Ignore if not registered */ 03340 if (!p->addr.sin_addr.s_addr) 03341 return 0; 03342 if (p->maxms && ((p->lastms < 0) || (p->lastms >= p->maxms))) 03343 return 0; 03344 if (ast_strlen_zero(dr->number)) 03345 ast_log(LOG_DEBUG, "Will query peer '%s' for '%s' (context '%s')\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &p->eid), dundi_eid_to_str(eid_str2, sizeof(eid_str2), &dr->query_eid), dr->dcontext); 03346 else 03347 ast_log(LOG_DEBUG, "Will query peer '%s' for '%s@%s'\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &p->eid), dr->number, dr->dcontext); 03348 trans = create_transaction(p); 03349 if (!trans) 03350 return -1; 03351 trans->next = dr->trans; 03352 trans->parent = dr; 03353 trans->ttl = ttl; 03354 for (x=0;avoid[x] && (x <DUNDI_MAX_STACK);x++) 03355 trans->eids[x] = *avoid[x]; 03356 trans->eidcount = x; 03357 dr->trans = trans; 03358 return 0; 03359 }
static void apply_peer | ( | struct dundi_transaction * | trans, | |
struct dundi_peer * | p | |||
) | [static] |
Definition at line 1261 of file pbx_dundi.c.
References dundi_peer::addr, dundi_transaction::addr, ast_set_flag, ast_strlen_zero(), dundi_transaction::autokilltimeout, DUNDI_DEFAULT_RETRANS_TIMER, dundi_peer::eid, FLAG_ENCRYPT, global_autokilltimeout, dundi_peer::inkey, dundi_peer::lastms, dundi_peer::maxms, dundi_transaction::retranstimer, dundi_transaction::them_eid, dundi_peer::us_eid, and dundi_transaction::us_eid.
Referenced by create_transaction().
01262 { 01263 if (!trans->addr.sin_addr.s_addr) 01264 memcpy(&trans->addr, &p->addr, sizeof(trans->addr)); 01265 trans->us_eid = p->us_eid; 01266 trans->them_eid = p->eid; 01267 /* Enable encryption if appropriate */ 01268 if (!ast_strlen_zero(p->inkey)) 01269 ast_set_flag(trans, FLAG_ENCRYPT); 01270 if (p->maxms) { 01271 trans->autokilltimeout = p->maxms; 01272 trans->retranstimer = DUNDI_DEFAULT_RETRANS_TIMER; 01273 if (p->lastms > 1) { 01274 trans->retranstimer = p->lastms * 2; 01275 /* Keep it from being silly */ 01276 if (trans->retranstimer < 150) 01277 trans->retranstimer = 150; 01278 } 01279 if (trans->retranstimer > DUNDI_DEFAULT_RETRANS_TIMER) 01280 trans->retranstimer = DUNDI_DEFAULT_RETRANS_TIMER; 01281 } else 01282 trans->autokilltimeout = global_autokilltimeout; 01283 }
AST_MUTEX_DEFINE_STATIC | ( | pclock | ) |
AST_MUTEX_DEFINE_STATIC | ( | peerlock | ) |
static unsigned long avoid_crc32 | ( | dundi_eid * | avoid[] | ) | [static] |
Definition at line 3518 of file pbx_dundi.c.
References dundi_request::crc32.
Referenced by dundi_lookup_internal().
03519 { 03520 /* Idea is that we're calculating a checksum which is independent of 03521 the order that the EID's are listed in */ 03522 unsigned long acrc32 = 0; 03523 int x; 03524 for (x=0;avoid[x];x++) { 03525 /* Order doesn't matter */ 03526 if (avoid[x+1]) { 03527 acrc32 ^= crc32(0L, (unsigned char *)avoid[x], sizeof(dundi_eid)); 03528 } 03529 } 03530 return acrc32; 03531 }
static void build_iv | ( | unsigned char * | iv | ) | [static] |
Definition at line 503 of file pbx_dundi.c.
Referenced by build_secret(), dundi_encrypt(), and update_key().
00504 { 00505 /* XXX Would be nice to be more random XXX */ 00506 unsigned int *fluffy; 00507 int x; 00508 fluffy = (unsigned int *)(iv); 00509 for (x=0;x<4;x++) 00510 fluffy[x] = rand(); 00511 }
static void build_mapping | ( | char * | name, | |
char * | value | |||
) | [static] |
Definition at line 4120 of file pbx_dundi.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), dundi_mapping::dead, DUNDI_FLAG_COMMERCIAL, DUNDI_FLAG_INTERNAL_NOPARTIAL, DUNDI_FLAG_MOBILE, DUNDI_FLAG_NOCOMUNSOLICIT, DUNDI_FLAG_NOUNSOLICITED, DUNDI_FLAG_RESIDENTIAL, LOG_WARNING, malloc, map, mappings, MAX_OPTS, str2tech(), and t.
Referenced by set_config().
04121 { 04122 char *t, *fields[MAX_OPTS]; 04123 struct dundi_mapping *map; 04124 int x; 04125 int y; 04126 t = ast_strdupa(value); 04127 if (t) { 04128 map = mappings; 04129 while(map) { 04130 /* Find a double match */ 04131 if (!strcasecmp(map->dcontext, name) && 04132 (!strncasecmp(map->lcontext, value, strlen(map->lcontext)) && 04133 (!value[strlen(map->lcontext)] || 04134 (value[strlen(map->lcontext)] == ',')))) 04135 break; 04136 map = map->next; 04137 } 04138 if (!map) { 04139 map = malloc(sizeof(struct dundi_mapping)); 04140 if (map) { 04141 memset(map, 0, sizeof(struct dundi_mapping)); 04142 map->next = mappings; 04143 mappings = map; 04144 map->dead = 1; 04145 } 04146 } 04147 if (map) { 04148 map->options = 0; 04149 memset(fields, 0, sizeof(fields)); 04150 x = 0; 04151 while(t && x < MAX_OPTS) { 04152 fields[x++] = t; 04153 t = strchr(t, ','); 04154 if (t) { 04155 *t = '\0'; 04156 t++; 04157 } 04158 } /* Russell was here, arrrr! */ 04159 if ((x == 1) && ast_strlen_zero(fields[0])) { 04160 /* Placeholder mapping */ 04161 ast_copy_string(map->dcontext, name, sizeof(map->dcontext)); 04162 map->dead = 0; 04163 } else if (x >= 4) { 04164 ast_copy_string(map->dcontext, name, sizeof(map->dcontext)); 04165 ast_copy_string(map->lcontext, fields[0], sizeof(map->lcontext)); 04166 if ((sscanf(fields[1], "%d", &map->weight) == 1) && (map->weight >= 0) && (map->weight < 60000)) { 04167 ast_copy_string(map->dest, fields[3], sizeof(map->dest)); 04168 if ((map->tech = str2tech(fields[2]))) { 04169 map->dead = 0; 04170 } 04171 } else { 04172 ast_log(LOG_WARNING, "Invalid weight '%s' specified, deleting entry '%s/%s'\n", fields[1], map->dcontext, map->lcontext); 04173 } 04174 for (y=4;y<x;y++) { 04175 if (!strcasecmp(fields[y], "nounsolicited")) 04176 map->options |= DUNDI_FLAG_NOUNSOLICITED; 04177 else if (!strcasecmp(fields[y], "nocomunsolicit")) 04178 map->options |= DUNDI_FLAG_NOCOMUNSOLICIT; 04179 else if (!strcasecmp(fields[y], "residential")) 04180 map->options |= DUNDI_FLAG_RESIDENTIAL; 04181 else if (!strcasecmp(fields[y], "commercial")) 04182 map->options |= DUNDI_FLAG_COMMERCIAL; 04183 else if (!strcasecmp(fields[y], "mobile")) 04184 map->options |= DUNDI_FLAG_MOBILE; 04185 else if (!strcasecmp(fields[y], "nopartial")) 04186 map->options |= DUNDI_FLAG_INTERNAL_NOPARTIAL; 04187 else 04188 ast_log(LOG_WARNING, "Don't know anything about option '%s'\n", fields[y]); 04189 } 04190 } else 04191 ast_log(LOG_WARNING, "Expected at least %d arguments in map, but got only %d\n", 4, x); 04192 } 04193 } 04194 }
static void build_peer | ( | dundi_eid * | eid, | |
struct ast_variable * | v, | |||
int * | globalpcmode | |||
) | [static] |
Definition at line 4281 of file pbx_dundi.c.
References dundi_peer::addr, append_permission(), ast_gethostbyname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), ast_true(), dundi_peer::dead, DEFAULT_MAXMS, destroy_permissions(), do_register(), dundi_eid_cmp(), dundi_eid_to_str(), DUNDI_MODEL_INBOUND, DUNDI_MODEL_OUTBOUND, DUNDI_MODEL_SYMMETRIC, DUNDI_PORT, dundi_str_to_eid(), dundi_peer::dynamic, dundi_peer::eid, global_eid, hp, dundi_peer::include, dundi_peer::inkey, ast_variable::lineno, LOG_WARNING, malloc, dundi_peer::maxms, dundi_peer::model, ast_variable::name, ast_variable::next, dundi_peer::next, dundi_peer::order, dundi_peer::outkey, dundi_peer::pcmodel, peers, dundi_peer::permit, populate_addr(), qualify_peer(), dundi_peer::registerid, dundi_peer::us_eid, and ast_variable::value.
04282 { 04283 struct dundi_peer *peer; 04284 struct ast_hostent he; 04285 struct hostent *hp; 04286 dundi_eid testeid; 04287 int needregister=0; 04288 char eid_str[20]; 04289 04290 ast_mutex_lock(&peerlock); 04291 peer = peers; 04292 while(peer) { 04293 if (!dundi_eid_cmp(&peer->eid, eid)) { 04294 break; 04295 } 04296 peer = peer->next; 04297 } 04298 if (!peer) { 04299 /* Add us into the list */ 04300 peer = malloc(sizeof(struct dundi_peer)); 04301 if (peer) { 04302 memset(peer, 0, sizeof(struct dundi_peer)); 04303 peer->registerid = -1; 04304 peer->registerexpire = -1; 04305 peer->qualifyid = -1; 04306 peer->addr.sin_family = AF_INET; 04307 peer->addr.sin_port = htons(DUNDI_PORT); 04308 populate_addr(peer, eid); 04309 peer->next = peers; 04310 peers = peer; 04311 } 04312 } 04313 if (peer) { 04314 peer->dead = 0; 04315 peer->eid = *eid; 04316 peer->us_eid = global_eid; 04317 destroy_permissions(peer->permit); 04318 destroy_permissions(peer->include); 04319 peer->permit = NULL; 04320 peer->include = NULL; 04321 if (peer->registerid > -1) 04322 ast_sched_del(sched, peer->registerid); 04323 peer->registerid = -1; 04324 while(v) { 04325 if (!strcasecmp(v->name, "inkey")) { 04326 ast_copy_string(peer->inkey, v->value, sizeof(peer->inkey)); 04327 } else if (!strcasecmp(v->name, "outkey")) { 04328 ast_copy_string(peer->outkey, v->value, sizeof(peer->outkey)); 04329 } else if (!strcasecmp(v->name, "host")) { 04330 if (!strcasecmp(v->value, "dynamic")) { 04331 peer->dynamic = 1; 04332 } else { 04333 hp = ast_gethostbyname(v->value, &he); 04334 if (hp) { 04335 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); 04336 peer->dynamic = 0; 04337 } else { 04338 ast_log(LOG_WARNING, "Unable to find host '%s' at line %d\n", v->value, v->lineno); 04339 peer->dead = 1; 04340 } 04341 } 04342 } else if (!strcasecmp(v->name, "ustothem")) { 04343 if (!dundi_str_to_eid(&testeid, v->value)) 04344 peer->us_eid = testeid; 04345 else 04346 ast_log(LOG_WARNING, "'%s' is not a valid DUNDi Entity Identifier at line %d\n", v->value, v->lineno); 04347 } else if (!strcasecmp(v->name, "include")) { 04348 peer->include = append_permission(peer->include, v->value, 1); 04349 } else if (!strcasecmp(v->name, "permit")) { 04350 peer->permit = append_permission(peer->permit, v->value, 1); 04351 } else if (!strcasecmp(v->name, "noinclude")) { 04352 peer->include = append_permission(peer->include, v->value, 0); 04353 } else if (!strcasecmp(v->name, "deny")) { 04354 peer->permit = append_permission(peer->permit, v->value, 0); 04355 } else if (!strcasecmp(v->name, "register")) { 04356 needregister = ast_true(v->value); 04357 } else if (!strcasecmp(v->name, "order")) { 04358 if (!strcasecmp(v->value, "primary")) 04359 peer->order = 0; 04360 else if (!strcasecmp(v->value, "secondary")) 04361 peer->order = 1; 04362 else if (!strcasecmp(v->value, "tertiary")) 04363 peer->order = 2; 04364 else if (!strcasecmp(v->value, "quartiary")) 04365 peer->order = 3; 04366 else { 04367 ast_log(LOG_WARNING, "'%s' is not a valid order, should be primary, secondary, tertiary or quartiary at line %d\n", v->value, v->lineno); 04368 } 04369 } else if (!strcasecmp(v->name, "qualify")) { 04370 if (!strcasecmp(v->value, "no")) { 04371 peer->maxms = 0; 04372 } else if (!strcasecmp(v->value, "yes")) { 04373 peer->maxms = DEFAULT_MAXMS; 04374 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 04375 ast_log(LOG_WARNING, "Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of dundi.conf\n", 04376 dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid), v->lineno); 04377 peer->maxms = 0; 04378 } 04379 } else if (!strcasecmp(v->name, "model")) { 04380 if (!strcasecmp(v->value, "inbound")) 04381 peer->model = DUNDI_MODEL_INBOUND; 04382 else if (!strcasecmp(v->value, "outbound")) 04383 peer->model = DUNDI_MODEL_OUTBOUND; 04384 else if (!strcasecmp(v->value, "symmetric")) 04385 peer->model = DUNDI_MODEL_SYMMETRIC; 04386 else if (!strcasecmp(v->value, "none")) 04387 peer->model = 0; 04388 else { 04389 ast_log(LOG_WARNING, "Unknown model '%s', should be 'none', 'outbound', 'inbound', or 'symmetric' at line %d\n", 04390 v->value, v->lineno); 04391 } 04392 } else if (!strcasecmp(v->name, "precache")) { 04393 if (!strcasecmp(v->value, "inbound")) 04394 peer->pcmodel = DUNDI_MODEL_INBOUND; 04395 else if (!strcasecmp(v->value, "outbound")) 04396 peer->pcmodel = DUNDI_MODEL_OUTBOUND; 04397 else if (!strcasecmp(v->value, "symmetric")) 04398 peer->pcmodel = DUNDI_MODEL_SYMMETRIC; 04399 else if (!strcasecmp(v->value, "none")) 04400 peer->pcmodel = 0; 04401 else { 04402 ast_log(LOG_WARNING, "Unknown pcmodel '%s', should be 'none', 'outbound', 'inbound', or 'symmetric' at line %d\n", 04403 v->value, v->lineno); 04404 } 04405 } 04406 v = v->next; 04407 } 04408 (*globalpcmode) |= peer->pcmodel; 04409 if (!peer->model && !peer->pcmodel) { 04410 ast_log(LOG_WARNING, "Peer '%s' lacks a model or pcmodel, discarding!\n", 04411 dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid)); 04412 peer->dead = 1; 04413 } else if ((peer->model & DUNDI_MODEL_INBOUND) && (peer->pcmodel & DUNDI_MODEL_OUTBOUND)) { 04414 ast_log(LOG_WARNING, "Peer '%s' may not be both inbound/symmetric model and outbound/symmetric precache model, discarding!\n", 04415 dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid)); 04416 peer->dead = 1; 04417 } else if ((peer->model & DUNDI_MODEL_OUTBOUND) && (peer->pcmodel & DUNDI_MODEL_INBOUND)) { 04418 ast_log(LOG_WARNING, "Peer '%s' may not be both outbound/symmetric model and inbound/symmetric precache model, discarding!\n", 04419 dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid)); 04420 peer->dead = 1; 04421 } else if (peer->include && !(peer->model & DUNDI_MODEL_OUTBOUND) && !(peer->pcmodel & DUNDI_MODEL_INBOUND)) { 04422 ast_log(LOG_WARNING, "Peer '%s' is supposed to be included in outbound searches but isn't an outbound peer or inbound precache!\n", 04423 dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid)); 04424 } else if (peer->permit && !(peer->model & DUNDI_MODEL_INBOUND) && !(peer->pcmodel & DUNDI_MODEL_OUTBOUND)) { 04425 ast_log(LOG_WARNING, "Peer '%s' is supposed to have permission for some inbound searches but isn't an inbound peer or outbound precache!\n", 04426 dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid)); 04427 } else { 04428 if (needregister) { 04429 peer->registerid = ast_sched_add(sched, 2000, do_register, peer); 04430 } 04431 qualify_peer(peer, 1); 04432 } 04433 } 04434 ast_mutex_unlock(&peerlock); 04435 }
static void build_secret | ( | char * | secret, | |
int | seclen | |||
) | [static] |
Definition at line 2011 of file pbx_dundi.c.
References ast_base64encode(), build_iv(), and s.
Referenced by check_password(), and load_password().
02012 { 02013 unsigned char tmp[16]; 02014 char *s; 02015 build_iv(tmp); 02016 secret[0] = '\0'; 02017 ast_base64encode(secret, tmp, sizeof(tmp), seclen); 02018 /* Eliminate potential bad characters */ 02019 while((s = strchr(secret, ';'))) *s = '+'; 02020 while((s = strchr(secret, '/'))) *s = '+'; 02021 while((s = strchr(secret, ':'))) *s = '+'; 02022 while((s = strchr(secret, '@'))) *s = '+'; 02023 }
static void build_transactions | ( | struct dundi_request * | dr, | |
int | ttl, | |||
int | order, | |||
int * | foundcache, | |||
int * | skipped, | |||
int | blockempty, | |||
int | nocache, | |||
int | modeselect, | |||
dundi_eid * | skip, | |||
dundi_eid * | avoid[], | |||
int | directs[] | |||
) | [static] |
Definition at line 3388 of file pbx_dundi.c.
References append_transaction(), ast_clear_flag_nonstd, ast_log(), ast_mutex_lock(), cache_lookup(), dr, dundi_eid_cmp(), dundi_eid_to_str(), dundi_eid_zero(), DUNDI_HINT_UNAFFECTED, DUNDI_MODEL_OUTBOUND, dundi_peer::eid, has_permission(), dundi_peer::include, LOG_DEBUG, dundi_peer::model, dundi_peer::order, pass, dundi_peer::pcmodel, peers, dundi_peer::permit, and dundi_peer::us_eid.
Referenced by dundi_lookup_internal(), dundi_precache_internal(), and dundi_query_eid_internal().
03389 { 03390 struct dundi_peer *p; 03391 int x; 03392 int res; 03393 int pass; 03394 int allowconnect; 03395 char eid_str[20]; 03396 ast_mutex_lock(&peerlock); 03397 p = peers; 03398 while(p) { 03399 if (modeselect == 1) { 03400 /* Send the precache to push upstreams only! */ 03401 pass = has_permission(p->permit, dr->dcontext) && (p->pcmodel & DUNDI_MODEL_OUTBOUND); 03402 allowconnect = 1; 03403 } else { 03404 /* Normal lookup / EID query */ 03405 pass = has_permission(p->include, dr->dcontext); 03406 allowconnect = p->model & DUNDI_MODEL_OUTBOUND; 03407 } 03408 if (skip) { 03409 if (!dundi_eid_cmp(skip, &p->eid)) 03410 pass = 0; 03411 } 03412 if (pass) { 03413 if (p->order <= order) { 03414 /* Check order first, then check cache, regardless of 03415 omissions, this gets us more likely to not have an 03416 affected answer. */ 03417 if((nocache || !(res = cache_lookup(dr, &p->eid, dr->crc32, &dr->expiration)))) { 03418 res = 0; 03419 /* Make sure we haven't already seen it and that it won't 03420 affect our answer */ 03421 for (x=0;avoid[x];x++) { 03422 if (!dundi_eid_cmp(avoid[x], &p->eid) || !dundi_eid_cmp(avoid[x], &p->us_eid)) { 03423 /* If not a direct connection, it affects our answer */ 03424 if (directs && !directs[x]) 03425 ast_clear_flag_nonstd(dr->hmd, DUNDI_HINT_UNAFFECTED); 03426 break; 03427 } 03428 } 03429 /* Make sure we can ask */ 03430 if (allowconnect) { 03431 if (!avoid[x] && (!blockempty || !dundi_eid_zero(&p->us_eid))) { 03432 /* Check for a matching or 0 cache entry */ 03433 append_transaction(dr, p, ttl, avoid); 03434 } else 03435 ast_log(LOG_DEBUG, "Avoiding '%s' in transaction\n", dundi_eid_to_str(eid_str, sizeof(eid_str), avoid[x])); 03436 } 03437 } 03438 *foundcache |= res; 03439 } else if (!*skipped || (p->order < *skipped)) 03440 *skipped = p->order; 03441 } 03442 p = p->next; 03443 } 03444 ast_mutex_unlock(&peerlock); 03445 }
static int cache_lookup | ( | struct dundi_request * | req, | |
dundi_eid * | peer_eid, | |||
unsigned long | crc32, | |||
int * | lowexpiration | |||
) | [static] |
Definition at line 1209 of file pbx_dundi.c.
References cache_lookup_internal(), dundi_request::dcontext, dundi_eid_to_str(), dundi_eid_to_str_short(), dundi_hint_metadata::exten, dundi_request::hmd, key(), dundi_request::number, dundi_request::respcount, and dundi_request::root_eid.
Referenced by build_transactions().
01210 { 01211 char key[256]; 01212 char eid_str[20]; 01213 char eidroot_str[20]; 01214 time_t now; 01215 int res=0; 01216 int res2=0; 01217 char eid_str_full[20]; 01218 char tmp[256]=""; 01219 int x; 01220 01221 time(&now); 01222 dundi_eid_to_str_short(eid_str, sizeof(eid_str), peer_eid); 01223 dundi_eid_to_str_short(eidroot_str, sizeof(eidroot_str), &req->root_eid); 01224 dundi_eid_to_str(eid_str_full, sizeof(eid_str_full), peer_eid); 01225 snprintf(key, sizeof(key), "%s/%s/%s/e%08lx", eid_str, req->number, req->dcontext, crc32); 01226 res |= cache_lookup_internal(now, req, key, eid_str_full, lowexpiration); 01227 snprintf(key, sizeof(key), "%s/%s/%s/e%08lx", eid_str, req->number, req->dcontext, 0L); 01228 res |= cache_lookup_internal(now, req, key, eid_str_full, lowexpiration); 01229 snprintf(key, sizeof(key), "%s/%s/%s/r%s", eid_str, req->number, req->dcontext, eidroot_str); 01230 res |= cache_lookup_internal(now, req, key, eid_str_full, lowexpiration); 01231 x = 0; 01232 if (!req->respcount) { 01233 while(!res2) { 01234 /* Look and see if we have a hint that would preclude us from looking at this 01235 peer for this number. */ 01236 if (!(tmp[x] = req->number[x])) 01237 break; 01238 x++; 01239 /* Check for hints */ 01240 snprintf(key, sizeof(key), "hint/%s/%s/%s/e%08lx", eid_str, tmp, req->dcontext, crc32); 01241 res2 |= cache_lookup_internal(now, req, key, eid_str_full, lowexpiration); 01242 snprintf(key, sizeof(key), "hint/%s/%s/%s/e%08lx", eid_str, tmp, req->dcontext, 0L); 01243 res2 |= cache_lookup_internal(now, req, key, eid_str_full, lowexpiration); 01244 snprintf(key, sizeof(key), "hint/%s/%s/%s/r%s", eid_str, tmp, req->dcontext, eidroot_str); 01245 res2 |= cache_lookup_internal(now, req, key, eid_str_full, lowexpiration); 01246 if (res2) { 01247 if (strlen(tmp) > strlen(req->hmd->exten)) { 01248 /* Update meta data if appropriate */ 01249 ast_copy_string(req->hmd->exten, tmp, sizeof(req->hmd->exten)); 01250 } 01251 } 01252 } 01253 res |= res2; 01254 } 01255 01256 return res; 01257 }
static int cache_lookup_internal | ( | time_t | now, | |
struct dundi_request * | req, | |||
char * | key, | |||
char * | eid_str_full, | |||
int * | lowexpiration | |||
) | [static] |
Definition at line 1137 of file pbx_dundi.c.
References ast_clear_flag_nonstd, ast_copy_flags, ast_db_del(), ast_db_get(), AST_FLAGS_ALL, ast_log(), dundi_result::dest, dundi_request::dr, dundi_eid_to_str(), dundi_flags2str(), DUNDI_HINT_DONT_ASK, dundi_str_short_to_eid(), ast_flags::flags, dundi_request::hmd, LOG_DEBUG, dundi_request::respcount, dundi_mapping::tech, tech2str(), dundi_result::techint, and dundi_result::weight.
Referenced by cache_lookup().
01138 { 01139 char data[1024]; 01140 char *ptr, *term, *src; 01141 int tech; 01142 struct ast_flags flags; 01143 int weight; 01144 int length; 01145 int z; 01146 int expiration; 01147 char fs[256]; 01148 time_t timeout; 01149 /* Build request string */ 01150 if (!ast_db_get("dundi/cache", key, data, sizeof(data))) { 01151 ptr = data; 01152 if (sscanf(ptr, "%d|%n", (int *)&timeout, &length) == 1) { 01153 expiration = timeout - now; 01154 if (expiration > 0) { 01155 ast_log(LOG_DEBUG, "Found cache expiring in %d seconds!\n", (int)(timeout - now)); 01156 ptr += length; 01157 while((sscanf(ptr, "%d/%d/%d/%n", &(flags.flags), &weight, &tech, &length) == 3)) { 01158 ptr += length; 01159 term = strchr(ptr, '|'); 01160 if (term) { 01161 *term = '\0'; 01162 src = strrchr(ptr, '/'); 01163 if (src) { 01164 *src = '\0'; 01165 src++; 01166 } else 01167 src = ""; 01168 ast_log(LOG_DEBUG, "Found cached answer '%s/%s' originally from '%s' with flags '%s' on behalf of '%s'\n", 01169 tech2str(tech), ptr, src, dundi_flags2str(fs, sizeof(fs), flags.flags), eid_str_full); 01170 /* Make sure it's not already there */ 01171 for (z=0;z<req->respcount;z++) { 01172 if ((req->dr[z].techint == tech) && 01173 !strcmp(req->dr[z].dest, ptr)) 01174 break; 01175 } 01176 if (z == req->respcount) { 01177 /* Copy into parent responses */ 01178 ast_copy_flags(&(req->dr[req->respcount]), &flags, AST_FLAGS_ALL); 01179 req->dr[req->respcount].weight = weight; 01180 req->dr[req->respcount].techint = tech; 01181 req->dr[req->respcount].expiration = expiration; 01182 dundi_str_short_to_eid(&req->dr[req->respcount].eid, src); 01183 dundi_eid_to_str(req->dr[req->respcount].eid_str, 01184 sizeof(req->dr[req->respcount].eid_str), &req->dr[req->respcount].eid); 01185 ast_copy_string(req->dr[req->respcount].dest, ptr, 01186 sizeof(req->dr[req->respcount].dest)); 01187 ast_copy_string(req->dr[req->respcount].tech, tech2str(tech), 01188 sizeof(req->dr[req->respcount].tech)); 01189 req->respcount++; 01190 ast_clear_flag_nonstd(req->hmd, DUNDI_HINT_DONT_ASK); 01191 } else if (req->dr[z].weight > weight) 01192 req->dr[z].weight = weight; 01193 ptr = term + 1; 01194 } 01195 } 01196 /* We found *something* cached */ 01197 if (expiration < *lowexpiration) 01198 *lowexpiration = expiration; 01199 return 1; 01200 } else 01201 ast_db_del("dundi/cache", key); 01202 } else 01203 ast_db_del("dundi/cache", key); 01204 } 01205 01206 return 0; 01207 }
static int cache_save | ( | dundi_eid * | eidpeer, | |
struct dundi_request * | req, | |||
int | start, | |||
int | unaffected, | |||
int | expiration, | |||
int | push | |||
) | [static] |
Definition at line 849 of file pbx_dundi.c.
References ast_db_put(), dundi_request::crc32, dundi_request::dcontext, dundi_result::dest, dundi_request::dr, dundi_cache_time, dundi_eid_to_str_short(), dundi_result::eid, dundi_result::flags, dundi_request::number, dundi_request::respcount, dundi_request::root_eid, dundi_result::techint, and dundi_result::weight.
Referenced by handle_command_response().
00850 { 00851 int x; 00852 char key1[256]; 00853 char key2[256]; 00854 char data[1024]; 00855 char eidpeer_str[20]; 00856 char eidroot_str[20]; 00857 time_t timeout; 00858 00859 if (expiration < 1) 00860 expiration = dundi_cache_time; 00861 00862 /* Keep pushes a little longer, cut pulls a little short */ 00863 if (push) 00864 expiration += 10; 00865 else 00866 expiration -= 10; 00867 if (expiration < 1) 00868 expiration = 1; 00869 dundi_eid_to_str_short(eidpeer_str, sizeof(eidpeer_str), eidpeer); 00870 dundi_eid_to_str_short(eidroot_str, sizeof(eidroot_str), &req->root_eid); 00871 snprintf(key1, sizeof(key1), "%s/%s/%s/e%08lx", eidpeer_str, req->number, req->dcontext, unaffected ? 0 : req->crc32); 00872 snprintf(key2, sizeof(key2), "%s/%s/%s/r%s", eidpeer_str, req->number, req->dcontext, eidroot_str); 00873 /* Build request string */ 00874 time(&timeout); 00875 timeout += expiration; 00876 snprintf(data, sizeof(data), "%ld|", (long)(timeout)); 00877 for (x=start;x<req->respcount;x++) { 00878 /* Skip anything with an illegal pipe in it */ 00879 if (strchr(req->dr[x].dest, '|')) 00880 continue; 00881 snprintf(data + strlen(data), sizeof(data) - strlen(data), "%d/%d/%d/%s/%s|", 00882 req->dr[x].flags, req->dr[x].weight, req->dr[x].techint, req->dr[x].dest, 00883 dundi_eid_to_str_short(eidpeer_str, sizeof(eidpeer_str), &req->dr[x].eid)); 00884 } 00885 ast_db_put("dundi/cache", key1, data); 00886 ast_db_put("dundi/cache", key2, data); 00887 return 0; 00888 }
static int cache_save_hint | ( | dundi_eid * | eidpeer, | |
struct dundi_request * | req, | |||
struct dundi_hint * | hint, | |||
int | expiration | |||
) | [static] |
Definition at line 814 of file pbx_dundi.c.
References ast_db_put(), ast_log(), ast_test_flag_nonstd, dundi_request::crc32, dundi_hint::data, dundi_request::dcontext, dundi_cache_time, dundi_eid_to_str_short(), DUNDI_HINT_DONT_ASK, DUNDI_HINT_UNAFFECTED, LOG_DEBUG, and dundi_request::root_eid.
Referenced by handle_command_response().
00815 { 00816 int unaffected; 00817 char key1[256]; 00818 char key2[256]; 00819 char eidpeer_str[20]; 00820 char eidroot_str[20]; 00821 char data[80]; 00822 time_t timeout; 00823 00824 if (expiration < 0) 00825 expiration = dundi_cache_time; 00826 00827 /* Only cache hint if "don't ask" is there... */ 00828 if (!ast_test_flag_nonstd(hint, htons(DUNDI_HINT_DONT_ASK))) 00829 return 0; 00830 00831 unaffected = ast_test_flag_nonstd(hint, htons(DUNDI_HINT_UNAFFECTED)); 00832 00833 dundi_eid_to_str_short(eidpeer_str, sizeof(eidpeer_str), eidpeer); 00834 dundi_eid_to_str_short(eidroot_str, sizeof(eidroot_str), &req->root_eid); 00835 snprintf(key1, sizeof(key1), "hint/%s/%s/%s/e%08lx", eidpeer_str, hint->data, req->dcontext, unaffected ? 0 : req->crc32); 00836 snprintf(key2, sizeof(key2), "hint/%s/%s/%s/r%s", eidpeer_str, hint->data, req->dcontext, eidroot_str); 00837 00838 time(&timeout); 00839 timeout += expiration; 00840 snprintf(data, sizeof(data), "%ld|", (long)(timeout)); 00841 00842 ast_db_put("dundi/cache", key1, data); 00843 ast_log(LOG_DEBUG, "Caching hint at '%s'\n", key1); 00844 ast_db_put("dundi/cache", key2, data); 00845 ast_log(LOG_DEBUG, "Caching hint at '%s'\n", key2); 00846 return 0; 00847 }
static void cancel_request | ( | struct dundi_request * | dr | ) | [static] |
Definition at line 3361 of file pbx_dundi.c.
References ast_mutex_lock(), ast_mutex_unlock(), dr, DUNDI_COMMAND_CANCEL, dundi_send(), dundi_transaction::next, and dundi_transaction::parent.
Referenced by dundi_lookup_internal(), and dundi_precache_internal().
03362 { 03363 struct dundi_transaction *trans, *next; 03364 03365 ast_mutex_lock(&peerlock); 03366 trans = dr->trans; 03367 03368 while(trans) { 03369 next = trans->next; 03370 /* Orphan transaction from request */ 03371 trans->parent = NULL; 03372 trans->next = NULL; 03373 /* Send final cancel */ 03374 dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, NULL); 03375 trans = next; 03376 } 03377 ast_mutex_unlock(&peerlock); 03378 }
static int check_key | ( | struct dundi_peer * | peer, | |
unsigned char * | newkey, | |||
unsigned char * | newsig, | |||
unsigned long | keycrc32 | |||
) | [static] |
Definition at line 1460 of file pbx_dundi.c.
References aes_decrypt_key128(), aes_encrypt_key128(), ast_check_signature_bin, ast_decrypt_bin, ast_key_get, AST_KEY_PRIVATE, AST_KEY_PUBLIC, ast_log(), dundi_eid_to_str(), dundi_peer::eid, dundi_peer::inkey, key(), LOG_DEBUG, LOG_NOTICE, option_debug, dundi_peer::outkey, dundi_peer::rxenckey, dundi_peer::them_dcx, dundi_peer::them_ecx, and dundi_peer::them_keycrc32.
01461 { 01462 unsigned char dst[128]; 01463 int res; 01464 struct ast_key *key, *skey; 01465 char eid_str[20]; 01466 if (option_debug) 01467 ast_log(LOG_DEBUG, "Expected '%08lx' got '%08lx'\n", peer->them_keycrc32, keycrc32); 01468 if (peer->them_keycrc32 && (peer->them_keycrc32 == keycrc32)) { 01469 /* A match */ 01470 return 1; 01471 } else if (!newkey || !newsig) 01472 return 0; 01473 if (!memcmp(peer->rxenckey, newkey, 128) && 01474 !memcmp(peer->rxenckey + 128, newsig, 128)) { 01475 /* By definition, a match */ 01476 return 1; 01477 } 01478 /* Decrypt key */ 01479 key = ast_key_get(peer->outkey, AST_KEY_PRIVATE); 01480 if (!key) { 01481 ast_log(LOG_NOTICE, "Unable to find key '%s' to decode shared key from '%s'\n", 01482 peer->outkey, dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid)); 01483 return -1; 01484 } 01485 01486 skey = ast_key_get(peer->inkey, AST_KEY_PUBLIC); 01487 if (!skey) { 01488 ast_log(LOG_NOTICE, "Unable to find key '%s' to verify shared key from '%s'\n", 01489 peer->inkey, dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid)); 01490 return -1; 01491 } 01492 01493 /* First check signature */ 01494 res = ast_check_signature_bin(skey, (char *)newkey, 128, newsig); 01495 if (res) 01496 return 0; 01497 01498 res = ast_decrypt_bin(dst, newkey, sizeof(dst), key); 01499 if (res != 16) { 01500 if (res >= 0) 01501 ast_log(LOG_NOTICE, "Weird, key decoded to the wrong size (%d)\n", res); 01502 return 0; 01503 } 01504 /* Decrypted, passes signature */ 01505 ast_log(LOG_DEBUG, "Wow, new key combo passed signature and decrypt!\n"); 01506 memcpy(peer->rxenckey, newkey, 128); 01507 memcpy(peer->rxenckey + 128, newsig, 128); 01508 peer->them_keycrc32 = crc32(0L, peer->rxenckey, 128); 01509 aes_decrypt_key128(dst, &peer->them_dcx); 01510 aes_encrypt_key128(dst, &peer->them_ecx); 01511 return 1; 01512 }
static void check_password | ( | void | ) | [static] |
Definition at line 2078 of file pbx_dundi.c.
References build_secret(), cursecret, rotatetime, and save_secret().
Referenced by network_thread().
02079 { 02080 char oldsecret[80]; 02081 time_t now; 02082 02083 time(&now); 02084 #if 0 02085 printf("%ld/%ld\n", now, rotatetime); 02086 #endif 02087 if ((now - rotatetime) >= 0) { 02088 /* Time to rotate keys */ 02089 ast_copy_string(oldsecret, cursecret, sizeof(oldsecret)); 02090 build_secret(cursecret, sizeof(cursecret)); 02091 save_secret(cursecret, oldsecret); 02092 } 02093 }
static int check_request | ( | struct dundi_request * | dr | ) | [static] |
Definition at line 3501 of file pbx_dundi.c.
References ast_mutex_lock(), ast_mutex_unlock(), dr, dundi_request::next, and requests.
Referenced by dundi_lookup_internal().
03502 { 03503 struct dundi_request *cur; 03504 int res = 0; 03505 ast_mutex_lock(&peerlock); 03506 cur = requests; 03507 while(cur) { 03508 if (cur == dr) { 03509 res = 1; 03510 break; 03511 } 03512 cur = cur->next; 03513 } 03514 ast_mutex_unlock(&peerlock); 03515 return res; 03516 }
static char* complete_peer_4 | ( | char * | line, | |
char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2268 of file pbx_dundi.c.
References complete_peer_helper().
02269 { 02270 return complete_peer_helper(line, word, pos, state, 3); 02271 }
static char* complete_peer_helper | ( | char * | line, | |
char * | word, | |||
int | pos, | |||
int | state, | |||
int | rpos | |||
) | [static] |
Definition at line 2243 of file pbx_dundi.c.
References ast_mutex_lock(), ast_mutex_unlock(), dundi_eid_to_str(), dundi_peer::eid, dundi_peer::next, peers, and strdup.
Referenced by complete_peer_4().
02244 { 02245 int which=0; 02246 char *ret; 02247 struct dundi_peer *p; 02248 char eid_str[20]; 02249 if (pos != rpos) 02250 return NULL; 02251 ast_mutex_lock(&peerlock); 02252 p = peers; 02253 while(p) { 02254 if (!strncasecmp(word, dundi_eid_to_str(eid_str, sizeof(eid_str), &p->eid), strlen(word))) { 02255 if (++which > state) 02256 break; 02257 } 02258 p = p->next; 02259 } 02260 if (p) { 02261 ret = strdup(dundi_eid_to_str(eid_str, sizeof(eid_str), &p->eid)); 02262 } else 02263 ret = NULL; 02264 ast_mutex_unlock(&peerlock); 02265 return ret; 02266 }
static struct dundi_transaction * create_transaction | ( | struct dundi_peer * | p | ) | [static] |
Definition at line 2776 of file pbx_dundi.c.
References dundi_peer::addr, alltrans, apply_peer(), ast_set_flag, DUNDI_DEFAULT_RETRANS_TIMER, FLAG_SENDFULLKEY, FLAG_STOREHIST, get_trans_id(), global_storehistory, malloc, and dundi_peer::sentfullkey.
Referenced by append_transaction(), do_register(), find_transaction(), and qualify_peer().
02777 { 02778 struct dundi_transaction *trans; 02779 int tid; 02780 02781 /* Don't allow creation of transactions to non-registered peers */ 02782 if (p && !p->addr.sin_addr.s_addr) 02783 return NULL; 02784 tid = get_trans_id(); 02785 if (tid < 1) 02786 return NULL; 02787 trans = malloc(sizeof(struct dundi_transaction)); 02788 if (trans) { 02789 memset(trans, 0, sizeof(struct dundi_transaction)); 02790 if (global_storehistory) { 02791 trans->start = ast_tvnow(); 02792 ast_set_flag(trans, FLAG_STOREHIST); 02793 } 02794 trans->retranstimer = DUNDI_DEFAULT_RETRANS_TIMER; 02795 trans->autokillid = -1; 02796 if (p) { 02797 apply_peer(trans, p); 02798 if (!p->sentfullkey) 02799 ast_set_flag(trans, FLAG_SENDFULLKEY); 02800 } 02801 trans->strans = tid; 02802 trans->allnext = alltrans; 02803 alltrans = trans; 02804 } 02805 return trans; 02806 }
static int decrypt_memcpy | ( | unsigned char * | dst, | |
unsigned char * | src, | |||
int | len, | |||
unsigned char * | iv, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 1352 of file pbx_dundi.c.
References aes_decrypt().
Referenced by dundi_decrypt().
01353 { 01354 unsigned char lastblock[16]; 01355 int x; 01356 memcpy(lastblock, iv, sizeof(lastblock)); 01357 while(len > 0) { 01358 aes_decrypt(src, dst, dcx); 01359 for (x=0;x<16;x++) 01360 dst[x] ^= lastblock[x]; 01361 memcpy(lastblock, src, sizeof(lastblock)); 01362 dst += 16; 01363 src += 16; 01364 len -= 16; 01365 } 01366 return 0; 01367 }
char* description | ( | void | ) |
Provides a description of the module.
Definition at line 4814 of file pbx_dundi.c.
References tdesc.
04815 { 04816 return tdesc; 04817 }
static void destroy_map | ( | struct dundi_mapping * | map | ) | [static] |
static void destroy_packet | ( | struct dundi_packet * | pack, | |
int | needfree | |||
) | [static] |
Definition at line 2825 of file pbx_dundi.c.
References ast_sched_del(), free, dundi_packet::next, dundi_transaction::packets, dundi_packet::parent, and dundi_packet::retransid.
Referenced by ack_trans().
02826 { 02827 struct dundi_packet *prev, *cur; 02828 if (pack->parent) { 02829 prev = NULL; 02830 cur = pack->parent->packets; 02831 while(cur) { 02832 if (cur == pack) { 02833 if (prev) 02834 prev->next = cur->next; 02835 else 02836 pack->parent->packets = cur->next; 02837 break; 02838 } 02839 prev = cur; 02840 cur = cur->next; 02841 } 02842 } 02843 if (pack->retransid > -1) 02844 ast_sched_del(sched, pack->retransid); 02845 if (needfree) 02846 free(pack); 02847 else { 02848 pack->retransid = -1; 02849 pack->next = NULL; 02850 } 02851 }
static void destroy_packets | ( | struct dundi_packet * | p | ) | [static] |
Definition at line 1905 of file pbx_dundi.c.
References ast_sched_del(), free, dundi_packet::next, and dundi_packet::retransid.
Referenced by ack_trans(), and handle_frame().
01906 { 01907 struct dundi_packet *prev; 01908 while(p) { 01909 prev = p; 01910 p = p->next; 01911 if (prev->retransid > -1) 01912 ast_sched_del(sched, prev->retransid); 01913 free(prev); 01914 } 01915 }
static void destroy_peer | ( | struct dundi_peer * | peer | ) | [static] |
Definition at line 4034 of file pbx_dundi.c.
References ast_sched_del(), destroy_permissions(), destroy_trans(), free, dundi_peer::include, dundi_peer::keypending, dundi_peer::permit, dundi_peer::qualifyid, dundi_peer::registerid, and dundi_peer::regtrans.
04035 { 04036 if (peer->registerid > -1) 04037 ast_sched_del(sched, peer->registerid); 04038 if (peer->regtrans) 04039 destroy_trans(peer->regtrans, 0); 04040 if (peer->keypending) 04041 destroy_trans(peer->keypending, 0); 04042 if (peer->qualifyid > -1) 04043 ast_sched_del(sched, peer->qualifyid); 04044 destroy_permissions(peer->permit); 04045 destroy_permissions(peer->include); 04046 free(peer); 04047 }
static void destroy_permissions | ( | struct permission * | p | ) | [static] |
Definition at line 4024 of file pbx_dundi.c.
References free, and permission::next.
Referenced by build_peer(), and destroy_peer().
04025 { 04026 struct permission *prev; 04027 while(p) { 04028 prev = p; 04029 p = p->next; 04030 free(prev); 04031 } 04032 }
static void destroy_trans | ( | struct dundi_transaction * | trans, | |
int | fromtimeout | |||
) | [static] |
Definition at line 2853 of file pbx_dundi.c.
References ast_log(), ast_strlen_zero(), ast_test_flag, dundi_peer::avgms, dundi_request::dcontext, dundi_eid_cmp(), dundi_eid_to_str(), DUNDI_TIMING_HISTORY, dundi_peer::eid, FLAG_ISQUAL, FLAG_ISREG, FLAG_STOREHIST, free, dundi_peer::keypending, dundi_peer::lastms, LOG_NOTICE, dundi_peer::lookups, dundi_peer::lookuptimes, malloc, dundi_peer::maxms, dundi_peer::next, dundi_request::number, dundi_transaction::parent, peers, dundi_peer::qualtrans, dundi_peer::qualtx, dundi_peer::regtrans, dundi_transaction::start, and dundi_transaction::them_eid.
Referenced by abort_request(), destroy_peer(), do_autokill(), do_register(), dundi_lookup_thread(), dundi_precache_thread(), dundi_query_thread(), dundi_rexmit(), handle_frame(), precache_trans(), precache_transactions(), and qualify_peer().
02854 { 02855 struct dundi_transaction *cur, *prev; 02856 struct dundi_peer *peer; 02857 int ms; 02858 int x; 02859 int cnt; 02860 char eid_str[20]; 02861 if (ast_test_flag(trans, FLAG_ISREG | FLAG_ISQUAL | FLAG_STOREHIST)) { 02862 peer = peers; 02863 while (peer) { 02864 if (peer->regtrans == trans) 02865 peer->regtrans = NULL; 02866 if (peer->keypending == trans) 02867 peer->keypending = NULL; 02868 if (peer->qualtrans == trans) { 02869 if (fromtimeout) { 02870 if (peer->lastms > -1) 02871 ast_log(LOG_NOTICE, "Peer '%s' has become UNREACHABLE!\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid)); 02872 peer->lastms = -1; 02873 } else { 02874 ms = ast_tvdiff_ms(ast_tvnow(), peer->qualtx); 02875 if (ms < 1) 02876 ms = 1; 02877 if (ms < peer->maxms) { 02878 if ((peer->lastms >= peer->maxms) || (peer->lastms < 0)) 02879 ast_log(LOG_NOTICE, "Peer '%s' has become REACHABLE!\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid)); 02880 } else if (peer->lastms < peer->maxms) { 02881 ast_log(LOG_NOTICE, "Peer '%s' has become TOO LAGGED (%d ms)\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid), ms); 02882 } 02883 peer->lastms = ms; 02884 } 02885 peer->qualtrans = NULL; 02886 } 02887 if (ast_test_flag(trans, FLAG_STOREHIST)) { 02888 if (trans->parent && !ast_strlen_zero(trans->parent->number)) { 02889 if (!dundi_eid_cmp(&trans->them_eid, &peer->eid)) { 02890 peer->avgms = 0; 02891 cnt = 0; 02892 if (peer->lookups[DUNDI_TIMING_HISTORY-1]) 02893 free(peer->lookups[DUNDI_TIMING_HISTORY-1]); 02894 for (x=DUNDI_TIMING_HISTORY-1;x>0;x--) { 02895 peer->lookuptimes[x] = peer->lookuptimes[x-1]; 02896 peer->lookups[x] = peer->lookups[x-1]; 02897 if (peer->lookups[x]) { 02898 peer->avgms += peer->lookuptimes[x]; 02899 cnt++; 02900 } 02901 } 02902 peer->lookuptimes[0] = ast_tvdiff_ms(ast_tvnow(), trans->start); 02903 peer->lookups[0] = malloc(strlen(trans->parent->number) + strlen(trans->parent->dcontext) + 2); 02904 if (peer->lookups[0]) { 02905 sprintf(peer->lookups[0], "%s@%s", trans->parent->number, trans->parent->dcontext); 02906 peer->avgms += peer->lookuptimes[0]; 02907 cnt++; 02908 } 02909 if (cnt) 02910 peer->avgms /= cnt; 02911 } 02912 } 02913 } 02914 peer = peer->next; 02915 } 02916 } 02917 if (trans->parent) { 02918 /* Unlink from parent if appropriate */ 02919 prev = NULL; 02920 cur = trans->parent->trans; 02921 while(cur) { 02922 if (cur == trans) { 02923 if (prev) 02924 prev->next = trans->next; 02925 else 02926 trans->parent->trans = trans->next; 02927 break; 02928 } 02929 prev = cur; 02930 cur = cur->next; 02931 } 02932 if (!trans->parent->trans) { 02933 /* Wake up sleeper */ 02934 if (trans->parent->pfds[1] > -1) { 02935 write(trans->parent->pfds[1], "killa!", 6); 02936 } 02937 } 02938 } 02939 /* Unlink from all trans */ 02940 prev = NULL; 02941 cur = alltrans; 02942 while(cur) { 02943 if (cur == trans) { 02944 if (prev) 02945 prev->allnext = trans->allnext; 02946 else 02947 alltrans = trans->allnext; 02948 break; 02949 } 02950 prev = cur; 02951 cur = cur->allnext; 02952 } 02953 destroy_packets(trans->packets); 02954 destroy_packets(trans->lasttrans); 02955 trans->packets = NULL; 02956 trans->lasttrans = NULL; 02957 if (trans->autokillid > -1) 02958 ast_sched_del(sched, trans->autokillid); 02959 trans->autokillid = -1; 02960 if (trans->thread) { 02961 /* If used by a thread, mark as dead and be done */ 02962 ast_set_flag(trans, FLAG_DEAD); 02963 } else 02964 free(trans); 02965 }
static int discover_transactions | ( | struct dundi_request * | dr | ) | [static] |
Definition at line 3212 of file pbx_dundi.c.
References ast_mutex_lock(), ast_mutex_unlock(), dr, and dundi_discover().
Referenced by dundi_lookup_internal().
03213 { 03214 struct dundi_transaction *trans; 03215 ast_mutex_lock(&peerlock); 03216 trans = dr->trans; 03217 while(trans) { 03218 dundi_discover(trans); 03219 trans = trans->next; 03220 } 03221 ast_mutex_unlock(&peerlock); 03222 return 0; 03223 }
static int do_autokill | ( | void * | data | ) | [static] |
Definition at line 3065 of file pbx_dundi.c.
References ast_log(), dundi_transaction::autokillid, destroy_trans(), dundi_eid_to_str(), LOG_NOTICE, and dundi_transaction::them_eid.
Referenced by dundi_discover(), dundi_query(), and precache_trans().
03066 { 03067 struct dundi_transaction *trans = data; 03068 char eid_str[20]; 03069 ast_log(LOG_NOTICE, "Transaction to '%s' took too long to ACK, destroying\n", 03070 dundi_eid_to_str(eid_str, sizeof(eid_str), &trans->them_eid)); 03071 trans->autokillid = -1; 03072 destroy_trans(trans, 0); /* We could actually set it to 1 instead of 0, but we won't ;-) */ 03073 return 0; 03074 }
static int do_qualify | ( | void * | data | ) | [static] |
Definition at line 4223 of file pbx_dundi.c.
References qualify_peer(), and dundi_peer::qualifyid.
Referenced by qualify_peer().
04224 { 04225 struct dundi_peer *peer; 04226 peer = data; 04227 peer->qualifyid = -1; 04228 qualify_peer(peer, 0); 04229 return 0; 04230 }
static int do_register | ( | void * | data | ) | [static] |
Definition at line 4196 of file pbx_dundi.c.
References ast_log(), ast_sched_add(), ast_set_flag, create_transaction(), default_expiration, destroy_trans(), DUNDI_COMMAND_REGREQ, DUNDI_DEFAULT_VERSION, dundi_eid_to_str(), dundi_ie_append_eid(), dundi_ie_append_short(), DUNDI_IE_EID, DUNDI_IE_EXPIRATION, DUNDI_IE_VERSION, dundi_send(), dundi_peer::eid, FLAG_ISREG, LOG_DEBUG, LOG_NOTICE, dundi_peer::registerid, dundi_peer::regtrans, dundi_transaction::us_eid, and dundi_peer::us_eid.
Referenced by build_peer().
04197 { 04198 struct dundi_ie_data ied; 04199 struct dundi_peer *peer = data; 04200 char eid_str[20]; 04201 char eid_str2[20]; 04202 /* Called with peerlock already held */ 04203 ast_log(LOG_DEBUG, "Register us as '%s' to '%s'\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->us_eid), dundi_eid_to_str(eid_str2, sizeof(eid_str2), &peer->eid)); 04204 peer->registerid = ast_sched_add(sched, default_expiration * 1000, do_register, data); 04205 /* Destroy old transaction if there is one */ 04206 if (peer->regtrans) 04207 destroy_trans(peer->regtrans, 0); 04208 peer->regtrans = create_transaction(peer); 04209 if (peer->regtrans) { 04210 ast_set_flag(peer->regtrans, FLAG_ISREG); 04211 memset(&ied, 0, sizeof(ied)); 04212 dundi_ie_append_short(&ied, DUNDI_IE_VERSION, DUNDI_DEFAULT_VERSION); 04213 dundi_ie_append_eid(&ied, DUNDI_IE_EID, &peer->regtrans->us_eid); 04214 dundi_ie_append_short(&ied, DUNDI_IE_EXPIRATION, default_expiration); 04215 dundi_send(peer->regtrans, DUNDI_COMMAND_REGREQ, 0, 0, &ied); 04216 04217 } else 04218 ast_log(LOG_NOTICE, "Unable to create new transaction for registering to '%s'!\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid)); 04219 04220 return 0; 04221 }
static int do_register_expire | ( | void * | data | ) | [static] |
Definition at line 1285 of file pbx_dundi.c.
References dundi_peer::addr, ast_log(), dundi_eid_to_str(), dundi_peer::eid, dundi_peer::lastms, LOG_DEBUG, and dundi_peer::registerexpire.
Referenced by handle_command_response(), and populate_addr().
01286 { 01287 struct dundi_peer *peer = data; 01288 char eid_str[20]; 01289 /* Called with peerlock already held */ 01290 ast_log(LOG_DEBUG, "Register expired for '%s'\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid)); 01291 peer->registerexpire = -1; 01292 peer->lastms = 0; 01293 memset(&peer->addr, 0, sizeof(peer->addr)); 01294 return 0; 01295 }
static int dundi_ack | ( | struct dundi_transaction * | trans, | |
int | final | |||
) | [static] |
Definition at line 378 of file pbx_dundi.c.
References DUNDI_COMMAND_ACK, and dundi_send().
Referenced by handle_frame().
00379 { 00380 return dundi_send(trans, DUNDI_COMMAND_ACK, 0, final, NULL); 00381 }
static int dundi_answer_entity | ( | struct dundi_transaction * | trans, | |
struct dundi_ies * | ies, | |||
char * | ccontext | |||
) | [static] |
Definition at line 755 of file pbx_dundi.c.
References ast_log(), ast_pthread_create, DUNDI_CAUSE_GENERAL, DUNDI_COMMAND_EIDRESPONSE, dundi_eid_cmp(), dundi_eid_to_str(), dundi_ie_append_cause(), DUNDI_IE_CAUSE, dundi_query_thread(), dundi_send(), free, ies, LOG_DEBUG, LOG_WARNING, malloc, s, dundi_transaction::thread, dundi_query_state::trans, and dundi_transaction::ttl.
Referenced by handle_command_response().
00756 { 00757 struct dundi_query_state *st; 00758 int totallen; 00759 int x; 00760 int skipfirst=0; 00761 struct dundi_ie_data ied; 00762 char eid_str[20]; 00763 char *s; 00764 pthread_t lookupthread; 00765 pthread_attr_t attr; 00766 if (ies->eidcount > 1) { 00767 /* Since it is a requirement that the first EID is the authenticating host 00768 and the last EID is the root, it is permissible that the first and last EID 00769 could be the same. In that case, we should go ahead copy only the "root" section 00770 since we will not need it for authentication. */ 00771 if (!dundi_eid_cmp(ies->eids[0], ies->eids[ies->eidcount - 1])) 00772 skipfirst = 1; 00773 } 00774 totallen = sizeof(struct dundi_query_state); 00775 totallen += (ies->eidcount - skipfirst) * sizeof(dundi_eid); 00776 st = malloc(totallen); 00777 if (st) { 00778 memset(st, 0, totallen); 00779 ast_copy_string(st->called_context, ies->called_context, sizeof(st->called_context)); 00780 memcpy(&st->reqeid, ies->reqeid, sizeof(st->reqeid)); 00781 st->trans = trans; 00782 st->ttl = ies->ttl - 1; 00783 if (st->ttl < 0) 00784 st->ttl = 0; 00785 s = st->fluffy; 00786 for (x=skipfirst;ies->eids[x];x++) { 00787 st->eids[x-skipfirst] = (dundi_eid *)s; 00788 *st->eids[x-skipfirst] = *ies->eids[x]; 00789 s += sizeof(dundi_eid); 00790 } 00791 ast_log(LOG_DEBUG, "Answering EID query for '%s@%s'!\n", dundi_eid_to_str(eid_str, sizeof(eid_str), ies->reqeid), ies->called_context); 00792 pthread_attr_init(&attr); 00793 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 00794 trans->thread = 1; 00795 if (ast_pthread_create(&lookupthread, &attr, dundi_query_thread, st)) { 00796 trans->thread = 0; 00797 ast_log(LOG_WARNING, "Unable to create thread!\n"); 00798 free(st); 00799 memset(&ied, 0, sizeof(ied)); 00800 dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_GENERAL, "Out of threads"); 00801 dundi_send(trans, DUNDI_COMMAND_EIDRESPONSE, 0, 1, &ied); 00802 return -1; 00803 } 00804 } else { 00805 ast_log(LOG_WARNING, "Out of memory!\n"); 00806 memset(&ied, 0, sizeof(ied)); 00807 dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_GENERAL, "Out of memory"); 00808 dundi_send(trans, DUNDI_COMMAND_EIDRESPONSE, 0, 1, &ied); 00809 return -1; 00810 } 00811 return 0; 00812 }
static int dundi_answer_query | ( | struct dundi_transaction * | trans, | |
struct dundi_ies * | ies, | |||
char * | ccontext | |||
) | [static] |
Definition at line 1045 of file pbx_dundi.c.
References ast_log(), ast_pthread_create, dundi_mapping::dcontext, DUNDI_CAUSE_GENERAL, DUNDI_COMMAND_DPRESPONSE, dundi_eid_cmp(), dundi_ie_append_cause(), DUNDI_IE_CAUSE, dundi_lookup_thread(), dundi_send(), free, ies, LOG_DEBUG, LOG_WARNING, malloc, mappings, dundi_mapping::next, dundi_query_state::nummaps, s, dundi_transaction::thread, and dundi_transaction::ttl.
Referenced by handle_command_response().
01046 { 01047 struct dundi_query_state *st; 01048 int totallen; 01049 int x; 01050 struct dundi_ie_data ied; 01051 char *s; 01052 struct dundi_mapping *cur; 01053 int mapcount; 01054 int skipfirst = 0; 01055 01056 pthread_t lookupthread; 01057 pthread_attr_t attr; 01058 totallen = sizeof(struct dundi_query_state); 01059 /* Count matching map entries */ 01060 mapcount = 0; 01061 cur = mappings; 01062 while(cur) { 01063 if (!strcasecmp(cur->dcontext, ccontext)) 01064 mapcount++; 01065 cur = cur->next; 01066 } 01067 /* If no maps, return -1 immediately */ 01068 if (!mapcount) 01069 return -1; 01070 01071 if (ies->eidcount > 1) { 01072 /* Since it is a requirement that the first EID is the authenticating host 01073 and the last EID is the root, it is permissible that the first and last EID 01074 could be the same. In that case, we should go ahead copy only the "root" section 01075 since we will not need it for authentication. */ 01076 if (!dundi_eid_cmp(ies->eids[0], ies->eids[ies->eidcount - 1])) 01077 skipfirst = 1; 01078 } 01079 01080 totallen += mapcount * sizeof(struct dundi_mapping); 01081 totallen += (ies->eidcount - skipfirst) * sizeof(dundi_eid); 01082 st = malloc(totallen); 01083 if (st) { 01084 memset(st, 0, totallen); 01085 ast_copy_string(st->called_context, ies->called_context, sizeof(st->called_context)); 01086 ast_copy_string(st->called_number, ies->called_number, sizeof(st->called_number)); 01087 st->trans = trans; 01088 st->ttl = ies->ttl - 1; 01089 st->nocache = ies->cbypass; 01090 if (st->ttl < 0) 01091 st->ttl = 0; 01092 s = st->fluffy; 01093 for (x=skipfirst;ies->eids[x];x++) { 01094 st->eids[x-skipfirst] = (dundi_eid *)s; 01095 *st->eids[x-skipfirst] = *ies->eids[x]; 01096 st->directs[x-skipfirst] = ies->eid_direct[x]; 01097 s += sizeof(dundi_eid); 01098 } 01099 /* Append mappings */ 01100 x = 0; 01101 st->maps = (struct dundi_mapping *)s; 01102 cur = mappings; 01103 while(cur) { 01104 if (!strcasecmp(cur->dcontext, ccontext)) { 01105 if (x < mapcount) { 01106 st->maps[x] = *cur; 01107 st->maps[x].next = NULL; 01108 x++; 01109 } 01110 } 01111 cur = cur->next; 01112 } 01113 st->nummaps = mapcount; 01114 ast_log(LOG_DEBUG, "Answering query for '%s@%s'!\n", ies->called_number, ies->called_context); 01115 pthread_attr_init(&attr); 01116 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 01117 trans->thread = 1; 01118 if (ast_pthread_create(&lookupthread, &attr, dundi_lookup_thread, st)) { 01119 trans->thread = 0; 01120 ast_log(LOG_WARNING, "Unable to create thread!\n"); 01121 free(st); 01122 memset(&ied, 0, sizeof(ied)); 01123 dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_GENERAL, "Out of threads"); 01124 dundi_send(trans, DUNDI_COMMAND_DPRESPONSE, 0, 1, &ied); 01125 return -1; 01126 } 01127 } else { 01128 ast_log(LOG_WARNING, "Out of memory!\n"); 01129 memset(&ied, 0, sizeof(ied)); 01130 dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_GENERAL, "Out of memory"); 01131 dundi_send(trans, DUNDI_COMMAND_DPRESPONSE, 0, 1, &ied); 01132 return -1; 01133 } 01134 return 0; 01135 }
static int dundi_canmatch | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
Definition at line 4481 of file pbx_dundi.c.
References DUNDI_FLAG_CANMATCH, and dundi_helper().
04482 { 04483 return dundi_helper(chan, context, exten, priority, data, DUNDI_FLAG_CANMATCH); 04484 }
static void dundi_debug_output | ( | const char * | data | ) | [static] |
Definition at line 283 of file pbx_dundi.c.
References ast_verbose().
Referenced by load_module().
00284 { 00285 if (dundidebug) 00286 ast_verbose("%s", data); 00287 }
static struct dundi_hdr* dundi_decrypt | ( | struct dundi_transaction * | trans, | |
unsigned char * | dst, | |||
int * | dstlen, | |||
struct dundi_hdr * | ohdr, | |||
struct dundi_encblock * | src, | |||
int | srclen | |||
) | [static] |
Definition at line 1369 of file pbx_dundi.c.
References ast_log(), dundi_transaction::dcx, decrypt_memcpy(), dundi_encblock::encdata, dundi_encblock::iv, LOG_DEBUG, and space.
01370 { 01371 int space = *dstlen; 01372 unsigned long bytes; 01373 struct dundi_hdr *h; 01374 unsigned char *decrypt_space; 01375 decrypt_space = alloca(srclen); 01376 if (!decrypt_space) 01377 return NULL; 01378 decrypt_memcpy(decrypt_space, src->encdata, srclen, src->iv, &trans->dcx); 01379 /* Setup header */ 01380 h = (struct dundi_hdr *)dst; 01381 *h = *ohdr; 01382 bytes = space - 6; 01383 if (uncompress(dst + 6, &bytes, decrypt_space, srclen) != Z_OK) { 01384 ast_log(LOG_DEBUG, "Ouch, uncompress failed :(\n"); 01385 return NULL; 01386 } 01387 /* Update length */ 01388 *dstlen = bytes + 6; 01389 /* Return new header */ 01390 return h; 01391 }
static int dundi_discover | ( | struct dundi_transaction * | trans | ) | [static] |
Definition at line 3100 of file pbx_dundi.c.
References ast_log(), ast_sched_add(), dundi_transaction::autokillid, dundi_transaction::autokilltimeout, dundi_request::cbypass, dundi_request::dcontext, do_autokill(), DUNDI_COMMAND_DPDISCOVER, DUNDI_DEFAULT_VERSION, dundi_eid_zero(), dundi_ie_append(), dundi_ie_append_eid(), dundi_ie_append_eid_appropriately(), dundi_ie_append_short(), dundi_ie_append_str(), DUNDI_IE_CACHEBYPASS, DUNDI_IE_CALLED_CONTEXT, DUNDI_IE_CALLED_NUMBER, DUNDI_IE_EID_DIRECT, DUNDI_IE_TTL, DUNDI_IE_VERSION, dundi_send(), dundi_transaction::eidcount, dundi_transaction::eids, LOG_WARNING, dundi_request::number, dundi_transaction::parent, dundi_transaction::ttl, and dundi_transaction::us_eid.
Referenced by discover_transactions().
03101 { 03102 struct dundi_ie_data ied; 03103 int x; 03104 if (!trans->parent) { 03105 ast_log(LOG_WARNING, "Tried to discover a transaction with no parent?!?\n"); 03106 return -1; 03107 } 03108 memset(&ied, 0, sizeof(ied)); 03109 dundi_ie_append_short(&ied, DUNDI_IE_VERSION, DUNDI_DEFAULT_VERSION); 03110 if (!dundi_eid_zero(&trans->us_eid)) 03111 dundi_ie_append_eid(&ied, DUNDI_IE_EID_DIRECT, &trans->us_eid); 03112 for (x=0;x<trans->eidcount;x++) 03113 dundi_ie_append_eid_appropriately(&ied, trans->parent->dcontext, &trans->eids[x], &trans->us_eid); 03114 dundi_ie_append_str(&ied, DUNDI_IE_CALLED_NUMBER, trans->parent->number); 03115 dundi_ie_append_str(&ied, DUNDI_IE_CALLED_CONTEXT, trans->parent->dcontext); 03116 dundi_ie_append_short(&ied, DUNDI_IE_TTL, trans->ttl); 03117 if (trans->parent->cbypass) 03118 dundi_ie_append(&ied, DUNDI_IE_CACHEBYPASS); 03119 if (trans->autokilltimeout) 03120 trans->autokillid = ast_sched_add(sched, trans->autokilltimeout, do_autokill, trans); 03121 return dundi_send(trans, DUNDI_COMMAND_DPDISCOVER, 0, 0, &ied); 03122 }
static int dundi_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2158 of file pbx_dundi.c.
References ast_cli(), dundidebug, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02159 { 02160 if (argc != 2) 02161 return RESULT_SHOWUSAGE; 02162 dundidebug = 1; 02163 ast_cli(fd, "DUNDi Debugging Enabled\n"); 02164 return RESULT_SUCCESS; 02165 }
static int dundi_do_lookup | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2290 of file pbx_dundi.c.
References ast_cli(), context, dr, dundi_flags2str(), dundi_lookup(), MAX_RESULTS, RESULT_SHOWUSAGE, RESULT_SUCCESS, and sort_results().
02291 { 02292 int res; 02293 char tmp[256]; 02294 char fs[80] = ""; 02295 char *context; 02296 int x; 02297 int bypass = 0; 02298 struct dundi_result dr[MAX_RESULTS]; 02299 struct timeval start; 02300 if ((argc < 3) || (argc > 4)) 02301 return RESULT_SHOWUSAGE; 02302 if (argc > 3) { 02303 if (!strcasecmp(argv[3], "bypass")) 02304 bypass=1; 02305 else 02306 return RESULT_SHOWUSAGE; 02307 } 02308 ast_copy_string(tmp, argv[2], sizeof(tmp)); 02309 context = strchr(tmp, '@'); 02310 if (context) { 02311 *context = '\0'; 02312 context++; 02313 } 02314 start = ast_tvnow(); 02315 res = dundi_lookup(dr, MAX_RESULTS, NULL, context, tmp, bypass); 02316 02317 if (res < 0) 02318 ast_cli(fd, "DUNDi lookup returned error.\n"); 02319 else if (!res) 02320 ast_cli(fd, "DUNDi lookup returned no results.\n"); 02321 else 02322 sort_results(dr, res); 02323 for (x=0;x<res;x++) { 02324 ast_cli(fd, "%3d. %5d %s/%s (%s)\n", x + 1, dr[x].weight, dr[x].tech, dr[x].dest, dundi_flags2str(fs, sizeof(fs), dr[x].flags)); 02325 ast_cli(fd, " from %s, expires in %d s\n", dr[x].eid_str, dr[x].expiration); 02326 } 02327 ast_cli(fd, "DUNDi lookup completed in %d ms\n", ast_tvdiff_ms(ast_tvnow(), start)); 02328 return RESULT_SUCCESS; 02329 }
static int dundi_do_precache | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2331 of file pbx_dundi.c.
References ast_cli(), context, dundi_precache(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02332 { 02333 int res; 02334 char tmp[256]; 02335 char *context; 02336 struct timeval start; 02337 if ((argc < 3) || (argc > 3)) 02338 return RESULT_SHOWUSAGE; 02339 ast_copy_string(tmp, argv[2], sizeof(tmp)); 02340 context = strchr(tmp, '@'); 02341 if (context) { 02342 *context = '\0'; 02343 context++; 02344 } 02345 start = ast_tvnow(); 02346 res = dundi_precache(context, tmp); 02347 02348 if (res < 0) 02349 ast_cli(fd, "DUNDi precache returned error.\n"); 02350 else if (!res) 02351 ast_cli(fd, "DUNDi precache returned no error.\n"); 02352 ast_cli(fd, "DUNDi lookup completed in %d ms\n", ast_tvdiff_ms(ast_tvnow(), start)); 02353 return RESULT_SUCCESS; 02354 }
static int dundi_do_query | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2356 of file pbx_dundi.c.
References ast_cli(), context, dundi_entity_info::country, dundi_query_eid(), dundi_str_to_eid(), dundi_entity_info::email, dundi_entity_info::ipaddr, dundi_entity_info::locality, dundi_entity_info::org, dundi_entity_info::orgunit, dundi_entity_info::phone, RESULT_SHOWUSAGE, RESULT_SUCCESS, and dundi_entity_info::stateprov.
02357 { 02358 int res; 02359 char tmp[256]; 02360 char *context; 02361 dundi_eid eid; 02362 struct dundi_entity_info dei; 02363 if ((argc < 3) || (argc > 3)) 02364 return RESULT_SHOWUSAGE; 02365 if (dundi_str_to_eid(&eid, argv[2])) { 02366 ast_cli(fd, "'%s' is not a valid EID!\n", argv[2]); 02367 return RESULT_SHOWUSAGE; 02368 } 02369 ast_copy_string(tmp, argv[2], sizeof(tmp)); 02370 context = strchr(tmp, '@'); 02371 if (context) { 02372 *context = '\0'; 02373 context++; 02374 } 02375 res = dundi_query_eid(&dei, context, eid); 02376 if (res < 0) 02377 ast_cli(fd, "DUNDi Query EID returned error.\n"); 02378 else if (!res) 02379 ast_cli(fd, "DUNDi Query EID returned no results.\n"); 02380 else { 02381 ast_cli(fd, "DUNDi Query EID succeeded:\n"); 02382 ast_cli(fd, "Department: %s\n", dei.orgunit); 02383 ast_cli(fd, "Organization: %s\n", dei.org); 02384 ast_cli(fd, "City/Locality: %s\n", dei.locality); 02385 ast_cli(fd, "State/Province: %s\n", dei.stateprov); 02386 ast_cli(fd, "Country: %s\n", dei.country); 02387 ast_cli(fd, "E-mail: %s\n", dei.email); 02388 ast_cli(fd, "Phone: %s\n", dei.phone); 02389 ast_cli(fd, "IP Address: %s\n", dei.ipaddr); 02390 } 02391 return RESULT_SUCCESS; 02392 }
static int dundi_do_store_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2167 of file pbx_dundi.c.
References ast_cli(), global_storehistory, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02168 { 02169 if (argc != 3) 02170 return RESULT_SHOWUSAGE; 02171 global_storehistory = 1; 02172 ast_cli(fd, "DUNDi History Storage Enabled\n"); 02173 return RESULT_SUCCESS; 02174 }
static int dundi_encrypt | ( | struct dundi_transaction * | trans, | |
struct dundi_packet * | pack | |||
) | [static] |
Definition at line 1393 of file pbx_dundi.c.
References ast_log(), ast_set_flag, ast_test_flag, build_iv(), dundi_hdr::cmdflags, dundi_hdr::cmdresp, dundi_packet::data, dundi_packet::datalen, dundi_transaction::dcx, DUNDI_COMMAND_ENCRYPT, dundi_ie_append_eid(), dundi_ie_append_encdata(), dundi_ie_append_int(), dundi_ie_append_raw(), DUNDI_IE_EID, DUNDI_IE_ENCDATA, DUNDI_IE_KEYCRC32, DUNDI_IE_SHAREDKEY, DUNDI_IE_SIGNATURE, dundi_transaction::ecx, encrypt_memcpy(), find_peer(), FLAG_SENDFULLKEY, dundi_packet::h, dundi_hdr::ies, dundi_hdr::iseqno, LOG_DEBUG, LOG_NOTICE, dundi_hdr::oseqno, dundi_peer::sentfullkey, dundi_transaction::them_eid, dundi_peer::txenckey, update_key(), dundi_peer::us_dcx, dundi_peer::us_ecx, dundi_transaction::us_eid, and dundi_peer::us_keycrc32.
Referenced by dundi_send().
01394 { 01395 unsigned char *compress_space; 01396 int len; 01397 int res; 01398 unsigned long bytes; 01399 struct dundi_ie_data ied; 01400 struct dundi_peer *peer; 01401 unsigned char iv[16]; 01402 len = pack->datalen + pack->datalen / 100 + 42; 01403 compress_space = alloca(len); 01404 if (compress_space) { 01405 memset(compress_space, 0, len); 01406 /* We care about everthing save the first 6 bytes of header */ 01407 bytes = len; 01408 res = compress(compress_space, &bytes, pack->data + 6, pack->datalen - 6); 01409 if (res != Z_OK) { 01410 ast_log(LOG_DEBUG, "Ouch, compression failed!\n"); 01411 return -1; 01412 } 01413 memset(&ied, 0, sizeof(ied)); 01414 /* Say who we are */ 01415 if (!pack->h->iseqno && !pack->h->oseqno) { 01416 /* Need the key in the first copy */ 01417 if (!(peer = find_peer(&trans->them_eid))) 01418 return -1; 01419 if (update_key(peer)) 01420 return -1; 01421 if (!peer->sentfullkey) 01422 ast_set_flag(trans, FLAG_SENDFULLKEY); 01423 /* Append key data */ 01424 dundi_ie_append_eid(&ied, DUNDI_IE_EID, &trans->us_eid); 01425 if (ast_test_flag(trans, FLAG_SENDFULLKEY)) { 01426 dundi_ie_append_raw(&ied, DUNDI_IE_SHAREDKEY, peer->txenckey, 128); 01427 dundi_ie_append_raw(&ied, DUNDI_IE_SIGNATURE, peer->txenckey + 128, 128); 01428 } else { 01429 dundi_ie_append_int(&ied, DUNDI_IE_KEYCRC32, peer->us_keycrc32); 01430 } 01431 /* Setup contexts */ 01432 trans->ecx = peer->us_ecx; 01433 trans->dcx = peer->us_dcx; 01434 01435 /* We've sent the full key */ 01436 peer->sentfullkey = 1; 01437 } 01438 /* Build initialization vector */ 01439 build_iv(iv); 01440 /* Add the field, rounded up to 16 bytes */ 01441 dundi_ie_append_encdata(&ied, DUNDI_IE_ENCDATA, iv, NULL, ((bytes + 15) / 16) * 16); 01442 /* Copy the data */ 01443 if ((ied.pos + bytes) >= sizeof(ied.buf)) { 01444 ast_log(LOG_NOTICE, "Final packet too large!\n"); 01445 return -1; 01446 } 01447 encrypt_memcpy(ied.buf + ied.pos, compress_space, bytes, iv, &trans->ecx); 01448 ied.pos += ((bytes + 15) / 16) * 16; 01449 /* Reconstruct header */ 01450 pack->datalen = sizeof(struct dundi_hdr); 01451 pack->h->cmdresp = DUNDI_COMMAND_ENCRYPT; 01452 pack->h->cmdflags = 0; 01453 memcpy(pack->h->ies, ied.buf, ied.pos); 01454 pack->datalen += ied.pos; 01455 return 0; 01456 } 01457 return -1; 01458 }
static void dundi_error_output | ( | const char * | data | ) | [static] |
Definition at line 289 of file pbx_dundi.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
00290 { 00291 ast_log(LOG_WARNING, "%s", data); 00292 }
static int dundi_exec | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
int | newstack, | |||
const char * | data | |||
) | [static] |
Definition at line 4486 of file pbx_dundi.c.
References ast_log(), ast_strlen_zero(), ast_test_flag, DUNDI_FLAG_EXISTS, dundi_lookup(), ast_channel::exten, LOG_NOTICE, LOG_WARNING, ast_channel::macroexten, MAX_RESULTS, pbx_builtin_getvar_helper(), pbx_exec(), pbx_findapp(), and sort_results().
04487 { 04488 struct dundi_result results[MAX_RESULTS]; 04489 int res; 04490 int x=0; 04491 char req[1024]; 04492 struct ast_app *dial; 04493 04494 if (!strncasecmp(context, "macro-", 6)) { 04495 if (!chan) { 04496 ast_log(LOG_NOTICE, "Can't use macro mode without a channel!\n"); 04497 return -1; 04498 } 04499 /* If done as a macro, use macro extension */ 04500 if (!strcasecmp(exten, "s")) { 04501 exten = pbx_builtin_getvar_helper(chan, "ARG1"); 04502 if (ast_strlen_zero(exten)) 04503 exten = chan->macroexten; 04504 if (ast_strlen_zero(exten)) 04505 exten = chan->exten; 04506 if (ast_strlen_zero(exten)) { 04507 ast_log(LOG_WARNING, "Called in Macro mode with no ARG1 or MACRO_EXTEN?\n"); 04508 return -1; 04509 } 04510 } 04511 if (ast_strlen_zero(data)) 04512 data = "e164"; 04513 } else { 04514 if (ast_strlen_zero(data)) 04515 data = context; 04516 } 04517 res = dundi_lookup(results, MAX_RESULTS, chan, data, exten, 0); 04518 if (res > 0) { 04519 sort_results(results, res); 04520 for (x=0;x<res;x++) { 04521 if (ast_test_flag(results + x, DUNDI_FLAG_EXISTS)) { 04522 if (!--priority) 04523 break; 04524 } 04525 } 04526 } 04527 if (x < res) { 04528 /* Got a hit! */ 04529 snprintf(req, sizeof(req), "%s/%s", results[x].tech, results[x].dest); 04530 dial = pbx_findapp("Dial"); 04531 if (dial) 04532 res = pbx_exec(chan, dial, req, newstack); 04533 } else 04534 res = -1; 04535 return res; 04536 }
static int dundi_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
Definition at line 4476 of file pbx_dundi.c.
References DUNDI_FLAG_EXISTS, and dundi_helper().
04477 { 04478 return dundi_helper(chan, context, exten, priority, data, DUNDI_FLAG_EXISTS); 04479 }
static int dundi_flush | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2176 of file pbx_dundi.c.
References ast_cli(), ast_db_deltree(), ast_mutex_lock(), ast_mutex_unlock(), dundi_peer::avgms, DUNDI_TIMING_HISTORY, free, dundi_peer::lookups, dundi_peer::lookuptimes, dundi_peer::next, peers, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02177 { 02178 int stats=0; 02179 if ((argc < 2) || (argc > 3)) 02180 return RESULT_SHOWUSAGE; 02181 if (argc > 2) { 02182 if (!strcasecmp(argv[2], "stats")) 02183 stats = 1; 02184 else 02185 return RESULT_SHOWUSAGE; 02186 } 02187 if (stats) { 02188 /* Flush statistics */ 02189 struct dundi_peer *p; 02190 int x; 02191 ast_mutex_lock(&peerlock); 02192 p = peers; 02193 while(p) { 02194 for (x=0;x<DUNDI_TIMING_HISTORY;x++) { 02195 if (p->lookups[x]) 02196 free(p->lookups[x]); 02197 p->lookups[x] = NULL; 02198 p->lookuptimes[x] = 0; 02199 } 02200 p->avgms = 0; 02201 p = p->next; 02202 } 02203 ast_mutex_unlock(&peerlock); 02204 } else { 02205 ast_db_deltree("dundi/cache", NULL); 02206 ast_cli(fd, "DUNDi Cache Flushed\n"); 02207 } 02208 return RESULT_SUCCESS; 02209 }
static int dundi_helper | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | data, | |||
int | flag | |||
) | [static] |
Definition at line 4437 of file pbx_dundi.c.
References ast_log(), ast_strlen_zero(), ast_test_flag, dundi_lookup(), ast_channel::exten, LOG_NOTICE, LOG_WARNING, ast_channel::macroexten, MAX_RESULTS, and pbx_builtin_getvar_helper().
Referenced by dundi_canmatch(), dundi_exists(), and dundi_matchmore().
04438 { 04439 struct dundi_result results[MAX_RESULTS]; 04440 int res; 04441 int x; 04442 int found = 0; 04443 if (!strncasecmp(context, "macro-", 6)) { 04444 if (!chan) { 04445 ast_log(LOG_NOTICE, "Can't use macro mode without a channel!\n"); 04446 return -1; 04447 } 04448 /* If done as a macro, use macro extension */ 04449 if (!strcasecmp(exten, "s")) { 04450 exten = pbx_builtin_getvar_helper(chan, "ARG1"); 04451 if (ast_strlen_zero(exten)) 04452 exten = chan->macroexten; 04453 if (ast_strlen_zero(exten)) 04454 exten = chan->exten; 04455 if (ast_strlen_zero(exten)) { 04456 ast_log(LOG_WARNING, "Called in Macro mode with no ARG1 or MACRO_EXTEN?\n"); 04457 return -1; 04458 } 04459 } 04460 if (ast_strlen_zero(data)) 04461 data = "e164"; 04462 } else { 04463 if (ast_strlen_zero(data)) 04464 data = context; 04465 } 04466 res = dundi_lookup(results, MAX_RESULTS, chan, data, exten, 0); 04467 for (x=0;x<res;x++) { 04468 if (ast_test_flag(results + x, flag)) 04469 found++; 04470 } 04471 if (found >= priority) 04472 return 1; 04473 return 0; 04474 }
static void dundi_ie_append_eid_appropriately | ( | struct dundi_ie_data * | ied, | |
char * | context, | |||
dundi_eid * | eid, | |||
dundi_eid * | us | |||
) | [static] |
Definition at line 3076 of file pbx_dundi.c.
References ast_mutex_lock(), ast_mutex_unlock(), dundi_eid_cmp(), dundi_ie_append_eid(), DUNDI_IE_EID, DUNDI_IE_EID_DIRECT, dundi_peer::eid, has_permission(), dundi_peer::include, dundi_peer::next, and peers.
Referenced by dundi_discover().
03077 { 03078 struct dundi_peer *p; 03079 if (!dundi_eid_cmp(eid, us)) { 03080 dundi_ie_append_eid(ied, DUNDI_IE_EID_DIRECT, eid); 03081 return; 03082 } 03083 ast_mutex_lock(&peerlock); 03084 p = peers; 03085 while(p) { 03086 if (!dundi_eid_cmp(&p->eid, eid)) { 03087 if (has_permission(p->include, context)) 03088 dundi_ie_append_eid(ied, DUNDI_IE_EID_DIRECT, eid); 03089 else 03090 dundi_ie_append_eid(ied, DUNDI_IE_EID, eid); 03091 break; 03092 } 03093 p = p->next; 03094 } 03095 if (!p) 03096 dundi_ie_append_eid(ied, DUNDI_IE_EID, eid); 03097 ast_mutex_unlock(&peerlock); 03098 }
int dundi_lookup | ( | struct dundi_result * | result, | |
int | maxret, | |||
struct ast_channel * | chan, | |||
const char * | dcontext, | |||
const char * | number, | |||
int | cbypass | |||
) |
Lookup the given number in the given dundi context (or e164 if unspecified) using the given callerid (if specified) and return up to maxret results in the array specified. returns the number of results found or -1 on a hangup of teh channel.
Definition at line 3635 of file pbx_dundi.c.
References dundi_cache_time, DUNDI_HINT_DONT_ASK, DUNDI_HINT_UNAFFECTED, dundi_lookup_internal(), dundi_ttl, and result.
Referenced by dundi_do_lookup(), dundi_exec(), dundi_helper(), dundi_lookup_exec(), and dundifunc_read().
03636 { 03637 struct dundi_hint_metadata hmd; 03638 dundi_eid *avoid[1] = { NULL, }; 03639 int direct[1] = { 0, }; 03640 int expiration = dundi_cache_time; 03641 memset(&hmd, 0, sizeof(hmd)); 03642 hmd.flags = DUNDI_HINT_DONT_ASK | DUNDI_HINT_UNAFFECTED; 03643 return dundi_lookup_internal(result, maxret, chan, dcontext, number, dundi_ttl, 0, &hmd, &expiration, cbypass, 0, NULL, avoid, direct); 03644 }
static int dundi_lookup_internal | ( | struct dundi_result * | result, | |
int | maxret, | |||
struct ast_channel * | chan, | |||
const char * | dcontext, | |||
const char * | number, | |||
int | ttl, | |||
int | blockempty, | |||
struct dundi_hint_metadata * | md, | |||
int * | expiration, | |||
int | cybpass, | |||
int | modeselect, | |||
dundi_eid * | skip, | |||
dundi_eid * | avoid[], | |||
int | direct[] | |||
) | [static] |
Definition at line 3533 of file pbx_dundi.c.
References ast_channel::_softhangup, abort_request(), ast_log(), ast_set_flag_nonstd, ast_waitfor_n_fd(), avoid_crc32(), build_transactions(), cancel_request(), check_request(), discover_transactions(), dr, dundi_eid_cmp(), dundi_eid_to_str(), DUNDI_FLUFF_TIME, DUNDI_HINT_TTL_EXPIRED, DUNDI_TTL_TIME, LOG_DEBUG, LOG_WARNING, ast_channel::name, optimize_transactions(), register_request(), result, dundi_request::root_eid, and unregister_request().
Referenced by dundi_lookup(), dundi_lookup_thread(), and precache_trans().
03534 { 03535 int res; 03536 struct dundi_request dr, *pending; 03537 dundi_eid *rooteid=NULL; 03538 int x; 03539 int ttlms; 03540 int ms; 03541 int foundcache; 03542 int skipped=0; 03543 int order=0; 03544 char eid_str[20]; 03545 struct timeval start; 03546 03547 /* Don't do anthing for a hungup channel */ 03548 if (chan && chan->_softhangup) 03549 return 0; 03550 03551 ttlms = DUNDI_FLUFF_TIME + ttl * DUNDI_TTL_TIME; 03552 03553 for (x=0;avoid[x];x++) 03554 rooteid = avoid[x]; 03555 /* Now perform real check */ 03556 memset(&dr, 0, sizeof(dr)); 03557 if (pipe(dr.pfds)) { 03558 ast_log(LOG_WARNING, "pipe failed: %s\n" , strerror(errno)); 03559 return -1; 03560 } 03561 dr.dr = result; 03562 dr.hmd = hmd; 03563 dr.maxcount = maxret; 03564 dr.expiration = *expiration; 03565 dr.cbypass = cbypass; 03566 dr.crc32 = avoid_crc32(avoid); 03567 ast_copy_string(dr.dcontext, dcontext ? dcontext : "e164", sizeof(dr.dcontext)); 03568 ast_copy_string(dr.number, number, sizeof(dr.number)); 03569 if (rooteid) 03570 dr.root_eid = *rooteid; 03571 res = register_request(&dr, &pending); 03572 if (res) { 03573 /* Already a request */ 03574 if (rooteid && !dundi_eid_cmp(&dr.root_eid, &pending->root_eid)) { 03575 /* This is on behalf of someone else. Go ahead and close this out since 03576 they'll get their answer anyway. */ 03577 ast_log(LOG_DEBUG, "Oooh, duplicate request for '%s@%s' for '%s'\n", 03578 dr.number,dr.dcontext,dundi_eid_to_str(eid_str, sizeof(eid_str), &dr.root_eid)); 03579 close(dr.pfds[0]); 03580 close(dr.pfds[1]); 03581 return -2; 03582 } else { 03583 /* Wait for the cache to populate */ 03584 ast_log(LOG_DEBUG, "Waiting for similar request for '%s@%s' for '%s'\n", 03585 dr.number,dr.dcontext,dundi_eid_to_str(eid_str, sizeof(eid_str), &pending->root_eid)); 03586 start = ast_tvnow(); 03587 while(check_request(pending) && (ast_tvdiff_ms(ast_tvnow(), start) < ttlms) && (!chan || !chan->_softhangup)) { 03588 /* XXX Would be nice to have a way to poll/select here XXX */ 03589 /* XXX this is a busy wait loop!!! */ 03590 usleep(1); 03591 } 03592 /* Continue on as normal, our cache should kick in */ 03593 } 03594 } 03595 /* Create transactions */ 03596 do { 03597 order = skipped; 03598 skipped = 0; 03599 foundcache = 0; 03600 build_transactions(&dr, ttl, order, &foundcache, &skipped, blockempty, cbypass, modeselect, skip, avoid, direct); 03601 } while (skipped && !foundcache && !dr.trans); 03602 /* If no TTL, abort and return 0 now after setting TTL expired hint. Couldn't 03603 do this earlier because we didn't know if we were going to have transactions 03604 or not. */ 03605 if (!ttl) { 03606 ast_set_flag_nonstd(hmd, DUNDI_HINT_TTL_EXPIRED); 03607 abort_request(&dr); 03608 unregister_request(&dr); 03609 close(dr.pfds[0]); 03610 close(dr.pfds[1]); 03611 return 0; 03612 } 03613 03614 /* Optimize transactions */ 03615 optimize_transactions(&dr, order); 03616 /* Actually perform transactions */ 03617 discover_transactions(&dr); 03618 /* Wait for transaction to come back */ 03619 start = ast_tvnow(); 03620 while(dr.trans && (ast_tvdiff_ms(ast_tvnow(), start) < ttlms) && (!chan || !chan->_softhangup)) { 03621 ms = 100; 03622 ast_waitfor_n_fd(dr.pfds, 1, &ms, NULL); 03623 } 03624 if (chan && chan->_softhangup) 03625 ast_log(LOG_DEBUG, "Hrm, '%s' hungup before their query for %s@%s finished\n", chan->name, dr.number, dr.dcontext); 03626 cancel_request(&dr); 03627 unregister_request(&dr); 03628 res = dr.respcount; 03629 *expiration = dr.expiration; 03630 close(dr.pfds[0]); 03631 close(dr.pfds[1]); 03632 return res; 03633 }
static int dundi_lookup_local | ( | struct dundi_result * | dr, | |
struct dundi_mapping * | map, | |||
char * | called_number, | |||
dundi_eid * | us_eid, | |||
int | anscnt, | |||
struct dundi_hint_metadata * | hmd | |||
) | [static] |
Definition at line 529 of file pbx_dundi.c.
References ast_canmatch_extension(), ast_clear_flag, ast_clear_flag_nonstd, ast_copy_flags, ast_exists_extension(), AST_FLAGS_ALL, ast_ignore_pattern(), AST_LIST_EMPTY, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_matchmore_extension(), AST_MAX_EXTENSION, ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_var_assign(), ast_var_delete(), cursecret, dr, dundi_cache_time, dundi_eid_to_str(), DUNDI_FLAG_CANMATCH, DUNDI_FLAG_EXISTS, DUNDI_FLAG_IGNOREPAT, DUNDI_FLAG_INTERNAL_NOPARTIAL, DUNDI_FLAG_MATCHMORE, DUNDI_HINT_DONT_ASK, ast_flags::flags, ipaddr, map, pbx_substitute_variables_varshead(), and tech2str().
Referenced by dundi_lookup_thread(), and precache_trans().
00530 { 00531 struct ast_flags flags = {0}; 00532 int x; 00533 if (!ast_strlen_zero(map->lcontext)) { 00534 if (ast_exists_extension(NULL, map->lcontext, called_number, 1, NULL)) 00535 ast_set_flag(&flags, DUNDI_FLAG_EXISTS); 00536 if (ast_canmatch_extension(NULL, map->lcontext, called_number, 1, NULL)) 00537 ast_set_flag(&flags, DUNDI_FLAG_CANMATCH); 00538 if (ast_matchmore_extension(NULL, map->lcontext, called_number, 1, NULL)) 00539 ast_set_flag(&flags, DUNDI_FLAG_MATCHMORE); 00540 if (ast_ignore_pattern(map->lcontext, called_number)) 00541 ast_set_flag(&flags, DUNDI_FLAG_IGNOREPAT); 00542 00543 /* Clearly we can't say 'don't ask' anymore if we found anything... */ 00544 if (ast_test_flag(&flags, AST_FLAGS_ALL)) 00545 ast_clear_flag_nonstd(hmd, DUNDI_HINT_DONT_ASK); 00546 00547 if (map->options & DUNDI_FLAG_INTERNAL_NOPARTIAL) { 00548 /* Skip partial answers */ 00549 ast_clear_flag(&flags, DUNDI_FLAG_MATCHMORE|DUNDI_FLAG_CANMATCH); 00550 } 00551 if (ast_test_flag(&flags, AST_FLAGS_ALL)) { 00552 struct varshead headp; 00553 struct ast_var_t *newvariable; 00554 ast_set_flag(&flags, map->options & 0xffff); 00555 ast_copy_flags(dr + anscnt, &flags, AST_FLAGS_ALL); 00556 dr[anscnt].techint = map->tech; 00557 dr[anscnt].weight = map->weight; 00558 dr[anscnt].expiration = dundi_cache_time; 00559 ast_copy_string(dr[anscnt].tech, tech2str(map->tech), sizeof(dr[anscnt].tech)); 00560 dr[anscnt].eid = *us_eid; 00561 dundi_eid_to_str(dr[anscnt].eid_str, sizeof(dr[anscnt].eid_str), &dr[anscnt].eid); 00562 if (ast_test_flag(&flags, DUNDI_FLAG_EXISTS)) { 00563 AST_LIST_HEAD_INIT_NOLOCK(&headp); 00564 newvariable = ast_var_assign("NUMBER", called_number); 00565 AST_LIST_INSERT_HEAD(&headp, newvariable, entries); 00566 newvariable = ast_var_assign("EID", dr[anscnt].eid_str); 00567 AST_LIST_INSERT_HEAD(&headp, newvariable, entries); 00568 newvariable = ast_var_assign("SECRET", cursecret); 00569 AST_LIST_INSERT_HEAD(&headp, newvariable, entries); 00570 newvariable = ast_var_assign("IPADDR", ipaddr); 00571 AST_LIST_INSERT_HEAD(&headp, newvariable, entries); 00572 pbx_substitute_variables_varshead(&headp, map->dest, dr[anscnt].dest, sizeof(dr[anscnt].dest)); 00573 while (!AST_LIST_EMPTY(&headp)) { /* List Deletion. */ 00574 newvariable = AST_LIST_REMOVE_HEAD(&headp, entries); 00575 ast_var_delete(newvariable); 00576 } 00577 } else 00578 dr[anscnt].dest[0] = '\0'; 00579 anscnt++; 00580 } else { 00581 /* No answers... Find the fewest number of digits from the 00582 number for which we have no answer. */ 00583 char tmp[AST_MAX_EXTENSION]; 00584 for (x=0;x<AST_MAX_EXTENSION;x++) { 00585 tmp[x] = called_number[x]; 00586 if (!tmp[x]) 00587 break; 00588 if (!ast_canmatch_extension(NULL, map->lcontext, tmp, 1, NULL)) { 00589 /* Oops found something we can't match. If this is longer 00590 than the running hint, we have to consider it */ 00591 if (strlen(tmp) > strlen(hmd->exten)) { 00592 ast_copy_string(hmd->exten, tmp, sizeof(hmd->exten)); 00593 } 00594 break; 00595 } 00596 } 00597 } 00598 } 00599 return anscnt; 00600 }
static void* dundi_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 604 of file pbx_dundi.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_test_flag_nonstd, dundi_query_state::called_context, dundi_query_state::called_number, destroy_trans(), dundi_query_state::directs, dr, dundi_cache_time, DUNDI_CAUSE_DUPLICATE, DUNDI_COMMAND_DPRESPONSE, dundi_eid_to_str(), DUNDI_HINT_DONT_ASK, DUNDI_HINT_UNAFFECTED, DUNDI_IE_ANSWER, dundi_ie_append_answer(), dundi_ie_append_cause(), dundi_ie_append_hint(), dundi_ie_append_short(), DUNDI_IE_CAUSE, DUNDI_IE_EXPIRATION, DUNDI_IE_HINT, dundi_lookup_internal(), dundi_lookup_local(), dundi_send(), dundi_query_state::eids, FLAG_DEAD, dundi_hint_metadata::flags, free, LOG_DEBUG, dundi_query_state::maps, MAX_RESULTS, dundi_query_state::nocache, dundi_query_state::nummaps, dundi_transaction::thread, dundi_query_state::trans, dundi_query_state::ttl, and dundi_transaction::us_eid.
Referenced by dundi_answer_query().
00605 { 00606 struct dundi_query_state *st = data; 00607 struct dundi_result dr[MAX_RESULTS]; 00608 struct dundi_ie_data ied; 00609 struct dundi_hint_metadata hmd; 00610 char eid_str[20]; 00611 int res, x; 00612 int ouranswers=0; 00613 int max = 999999; 00614 int expiration = dundi_cache_time; 00615 00616 ast_log(LOG_DEBUG, "Whee, looking up '%s@%s' for '%s'\n", st->called_number, st->called_context, 00617 st->eids[0] ? dundi_eid_to_str(eid_str, sizeof(eid_str), st->eids[0]) : "ourselves"); 00618 memset(&ied, 0, sizeof(ied)); 00619 memset(&dr, 0, sizeof(dr)); 00620 memset(&hmd, 0, sizeof(hmd)); 00621 /* Assume 'don't ask for anything' and 'unaffected', no TTL expired */ 00622 hmd.flags = DUNDI_HINT_DONT_ASK | DUNDI_HINT_UNAFFECTED; 00623 for (x=0;x<st->nummaps;x++) 00624 ouranswers = dundi_lookup_local(dr, st->maps + x, st->called_number, &st->trans->us_eid, ouranswers, &hmd); 00625 if (ouranswers < 0) 00626 ouranswers = 0; 00627 for (x=0;x<ouranswers;x++) { 00628 if (dr[x].weight < max) 00629 max = dr[x].weight; 00630 } 00631 00632 if (max) { 00633 /* If we do not have a canonical result, keep looking */ 00634 res = dundi_lookup_internal(dr + ouranswers, MAX_RESULTS - ouranswers, NULL, st->called_context, st->called_number, st->ttl, 1, &hmd, &expiration, st->nocache, 0, NULL, st->eids, st->directs); 00635 if (res > 0) { 00636 /* Append answer in result */ 00637 ouranswers += res; 00638 } else { 00639 if ((res < -1) && (!ouranswers)) 00640 dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_DUPLICATE, "Duplicate Request Pending"); 00641 } 00642 } 00643 ast_mutex_lock(&peerlock); 00644 /* Truncate if "don't ask" isn't present */ 00645 if (!ast_test_flag_nonstd(&hmd, DUNDI_HINT_DONT_ASK)) 00646 hmd.exten[0] = '\0'; 00647 if (ast_test_flag(st->trans, FLAG_DEAD)) { 00648 ast_log(LOG_DEBUG, "Our transaction went away!\n"); 00649 st->trans->thread = 0; 00650 destroy_trans(st->trans, 0); 00651 } else { 00652 for (x=0;x<ouranswers;x++) { 00653 /* Add answers */ 00654 if (dr[x].expiration && (expiration > dr[x].expiration)) 00655 expiration = dr[x].expiration; 00656 dundi_ie_append_answer(&ied, DUNDI_IE_ANSWER, &dr[x].eid, dr[x].techint, dr[x].flags, dr[x].weight, dr[x].dest); 00657 } 00658 dundi_ie_append_hint(&ied, DUNDI_IE_HINT, hmd.flags, hmd.exten); 00659 dundi_ie_append_short(&ied, DUNDI_IE_EXPIRATION, expiration); 00660 dundi_send(st->trans, DUNDI_COMMAND_DPRESPONSE, 0, 1, &ied); 00661 st->trans->thread = 0; 00662 } 00663 ast_mutex_unlock(&peerlock); 00664 free(st); 00665 return NULL; 00666 }
static int dundi_matchmore | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
Definition at line 4538 of file pbx_dundi.c.
References DUNDI_FLAG_MATCHMORE, and dundi_helper().
04539 { 04540 return dundi_helper(chan, context, exten, priority, data, DUNDI_FLAG_MATCHMORE); 04541 }
static int dundi_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2211 of file pbx_dundi.c.
References ast_cli(), dundidebug, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02212 { 02213 if (argc != 3) 02214 return RESULT_SHOWUSAGE; 02215 dundidebug = 0; 02216 ast_cli(fd, "DUNDi Debugging Disabled\n"); 02217 return RESULT_SUCCESS; 02218 }
static int dundi_no_store_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2220 of file pbx_dundi.c.
References ast_cli(), global_storehistory, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02221 { 02222 if (argc != 4) 02223 return RESULT_SHOWUSAGE; 02224 global_storehistory = 0; 02225 ast_cli(fd, "DUNDi History Storage Disabled\n"); 02226 return RESULT_SUCCESS; 02227 }
int dundi_precache | ( | const char * | context, | |
const char * | number | |||
) |
Pre-cache to push upstream peers.
Definition at line 3793 of file pbx_dundi.c.
References dundi_precache_internal(), and dundi_ttl.
Referenced by dundi_do_precache(), and process_precache().
03794 { 03795 dundi_eid *avoid[1] = { NULL, }; 03796 return dundi_precache_internal(context, number, dundi_ttl, avoid); 03797 }
static void dundi_precache_full | ( | void | ) | [static] |
Definition at line 3690 of file pbx_dundi.c.
References ast_get_context_name(), ast_get_extension_name(), ast_lock_context(), ast_lock_contexts(), ast_log(), ast_unlock_context(), ast_unlock_contexts(), ast_walk_context_extensions(), ast_walk_contexts(), dundi_mapping::dcontext, dundi_mapping::lcontext, LOG_NOTICE, mappings, dundi_mapping::next, and reschedule_precache().
Referenced by set_config().
03691 { 03692 struct dundi_mapping *cur; 03693 struct ast_context *con; 03694 struct ast_exten *e; 03695 cur = mappings; 03696 while(cur) { 03697 ast_log(LOG_NOTICE, "Should precache context '%s'\n", cur->dcontext); 03698 ast_lock_contexts(); 03699 con = ast_walk_contexts(NULL); 03700 while(con) { 03701 if (!strcasecmp(cur->lcontext, ast_get_context_name(con))) { 03702 /* Found the match, now queue them all up */ 03703 ast_lock_context(con); 03704 e = ast_walk_context_extensions(con, NULL); 03705 while(e) { 03706 reschedule_precache(ast_get_extension_name(e), cur->dcontext, 0); 03707 e = ast_walk_context_extensions(con, e); 03708 } 03709 ast_unlock_context(con); 03710 } 03711 con = ast_walk_contexts(con); 03712 } 03713 ast_unlock_contexts(); 03714 cur = cur->next; 03715 } 03716 }
static int dundi_precache_internal | ( | const char * | context, | |
const char * | number, | |||
int | ttl, | |||
dundi_eid * | avoids[] | |||
) | [static] |
Definition at line 3718 of file pbx_dundi.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_waitfor_n_fd(), build_transactions(), cancel_request(), dr, dundi_cache_time, DUNDI_FLUFF_TIME, DUNDI_TTL_TIME, LOG_DEBUG, LOG_NOTICE, mappings, MAX_RESULTS, dundi_mapping::next, optimize_transactions(), precache_transactions(), and reschedule_precache().
Referenced by dundi_precache(), and dundi_precache_thread().
03719 { 03720 struct dundi_request dr; 03721 struct dundi_hint_metadata hmd; 03722 struct dundi_result dr2[MAX_RESULTS]; 03723 struct timeval start; 03724 struct dundi_mapping *maps=NULL, *cur; 03725 int nummaps; 03726 int foundanswers; 03727 int foundcache, skipped, ttlms, ms; 03728 if (!context) 03729 context = "e164"; 03730 ast_log(LOG_DEBUG, "Precache internal (%s@%s)!\n", number, context); 03731 03732 ast_mutex_lock(&peerlock); 03733 nummaps = 0; 03734 cur = mappings; 03735 while(cur) { 03736 if (!strcasecmp(cur->dcontext, context)) 03737 nummaps++; 03738 cur = cur->next; 03739 } 03740 if (nummaps) { 03741 maps = alloca(nummaps * sizeof(struct dundi_mapping)); 03742 nummaps = 0; 03743 if (maps) { 03744 cur = mappings; 03745 while(cur) { 03746 if (!strcasecmp(cur->dcontext, context)) 03747 maps[nummaps++] = *cur; 03748 cur = cur->next; 03749 } 03750 } 03751 } 03752 ast_mutex_unlock(&peerlock); 03753 if (!nummaps || !maps) 03754 return -1; 03755 ttlms = DUNDI_FLUFF_TIME + ttl * DUNDI_TTL_TIME; 03756 memset(&dr2, 0, sizeof(dr2)); 03757 memset(&dr, 0, sizeof(dr)); 03758 memset(&hmd, 0, sizeof(hmd)); 03759 dr.dr = dr2; 03760 ast_copy_string(dr.number, number, sizeof(dr.number)); 03761 ast_copy_string(dr.dcontext, context ? context : "e164", sizeof(dr.dcontext)); 03762 dr.maxcount = MAX_RESULTS; 03763 dr.expiration = dundi_cache_time; 03764 dr.hmd = &hmd; 03765 dr.pfds[0] = dr.pfds[1] = -1; 03766 pipe(dr.pfds); 03767 build_transactions(&dr, ttl, 0, &foundcache, &skipped, 0, 1, 1, NULL, avoids, NULL); 03768 optimize_transactions(&dr, 0); 03769 foundanswers = 0; 03770 precache_transactions(&dr, maps, nummaps, &dr.expiration, &foundanswers); 03771 if (foundanswers) { 03772 if (dr.expiration > 0) 03773 reschedule_precache(dr.number, dr.dcontext, dr.expiration); 03774 else 03775 ast_log(LOG_NOTICE, "Weird, expiration = %d, but need to precache for %s@%s?!\n", dr.expiration, dr.number, dr.dcontext); 03776 } 03777 start = ast_tvnow(); 03778 while(dr.trans && (ast_tvdiff_ms(ast_tvnow(), start) < ttlms)) { 03779 if (dr.pfds[0] > -1) { 03780 ms = 100; 03781 ast_waitfor_n_fd(dr.pfds, 1, &ms, NULL); 03782 } else 03783 usleep(1); 03784 } 03785 cancel_request(&dr); 03786 if (dr.pfds[0] > -1) { 03787 close(dr.pfds[0]); 03788 close(dr.pfds[1]); 03789 } 03790 return 0; 03791 }
static void* dundi_precache_thread | ( | void * | data | ) | [static] |
Definition at line 668 of file pbx_dundi.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_test_flag_nonstd, dundi_query_state::called_context, dundi_query_state::called_number, destroy_trans(), DUNDI_COMMAND_PRECACHERP, dundi_eid_to_str(), DUNDI_HINT_DONT_ASK, dundi_precache_internal(), dundi_send(), dundi_query_state::eids, dundi_hint_metadata::exten, FLAG_DEAD, free, LOG_DEBUG, dundi_transaction::thread, dundi_query_state::trans, and dundi_query_state::ttl.
00669 { 00670 struct dundi_query_state *st = data; 00671 struct dundi_ie_data ied; 00672 struct dundi_hint_metadata hmd; 00673 char eid_str[20]; 00674 00675 ast_log(LOG_DEBUG, "Whee, precaching '%s@%s' for '%s'\n", st->called_number, st->called_context, 00676 st->eids[0] ? dundi_eid_to_str(eid_str, sizeof(eid_str), st->eids[0]) : "ourselves"); 00677 memset(&ied, 0, sizeof(ied)); 00678 00679 /* Now produce precache */ 00680 dundi_precache_internal(st->called_context, st->called_number, st->ttl, st->eids); 00681 00682 ast_mutex_lock(&peerlock); 00683 /* Truncate if "don't ask" isn't present */ 00684 if (!ast_test_flag_nonstd(&hmd, DUNDI_HINT_DONT_ASK)) 00685 hmd.exten[0] = '\0'; 00686 if (ast_test_flag(st->trans, FLAG_DEAD)) { 00687 ast_log(LOG_DEBUG, "Our transaction went away!\n"); 00688 st->trans->thread = 0; 00689 destroy_trans(st->trans, 0); 00690 } else { 00691 dundi_send(st->trans, DUNDI_COMMAND_PRECACHERP, 0, 1, &ied); 00692 st->trans->thread = 0; 00693 } 00694 ast_mutex_unlock(&peerlock); 00695 free(st); 00696 return NULL; 00697 }
static int dundi_prop_precache | ( | struct dundi_transaction * | trans, | |
struct dundi_ies * | ies, | |||
char * | ccontext | |||
) | [static] |
Definition at line 890 of file pbx_dundi.c.
References ast_clear_flag_nonstd, dundi_result::dest, dundi_request::dr, dr, dundi_cache_time, dundi_eid_to_str(), DUNDI_HINT_DONT_ASK, DUNDI_HINT_UNAFFECTED, dundi_request::hmd, ies, MAX_RESULTS, dundi_request::maxcount, dundi_transaction::parent, dundi_request::respcount, s, tech2str(), dundi_result::techint, and dundi_result::weight.
Referenced by handle_command_response().
00891 { 00892 struct dundi_query_state *st; 00893 int totallen; 00894 int x,z; 00895 struct dundi_ie_data ied; 00896 char *s; 00897 struct dundi_result dr2[MAX_RESULTS]; 00898 struct dundi_request dr; 00899 struct dundi_hint_metadata hmd; 00900 00901 struct dundi_mapping *cur; 00902 int mapcount; 00903 int skipfirst = 0; 00904 00905 pthread_t lookupthread; 00906 pthread_attr_t attr; 00907 00908 memset(&dr2, 0, sizeof(dr2)); 00909 memset(&dr, 0, sizeof(dr)); 00910 memset(&hmd, 0, sizeof(hmd)); 00911 00912 /* Forge request structure to hold answers for cache */ 00913 hmd.flags = DUNDI_HINT_DONT_ASK | DUNDI_HINT_UNAFFECTED; 00914 dr.dr = dr2; 00915 dr.maxcount = MAX_RESULTS; 00916 dr.expiration = dundi_cache_time; 00917 dr.hmd = &hmd; 00918 dr.pfds[0] = dr.pfds[1] = -1; 00919 trans->parent = &dr; 00920 ast_copy_string(dr.dcontext, ies->called_context ? ies->called_context : "e164", sizeof(dr.dcontext)); 00921 ast_copy_string(dr.number, ies->called_number, sizeof(dr.number)); 00922 00923 for (x=0;x<ies->anscount;x++) { 00924 if (trans->parent->respcount < trans->parent->maxcount) { 00925 /* Make sure it's not already there */ 00926 for (z=0;z<trans->parent->respcount;z++) { 00927 if ((trans->parent->dr[z].techint == ies->answers[x]->protocol) && 00928 !strcmp(trans->parent->dr[z].dest, (char *)ies->answers[x]->data)) 00929 break; 00930 } 00931 if (z == trans->parent->respcount) { 00932 /* Copy into parent responses */ 00933 trans->parent->dr[trans->parent->respcount].flags = ntohs(ies->answers[x]->flags); 00934 trans->parent->dr[trans->parent->respcount].techint = ies->answers[x]->protocol; 00935 trans->parent->dr[trans->parent->respcount].weight = ntohs(ies->answers[x]->weight); 00936 trans->parent->dr[trans->parent->respcount].eid = ies->answers[x]->eid; 00937 if (ies->expiration > 0) 00938 trans->parent->dr[trans->parent->respcount].expiration = ies->expiration; 00939 else 00940 trans->parent->dr[trans->parent->respcount].expiration = dundi_cache_time; 00941 dundi_eid_to_str(trans->parent->dr[trans->parent->respcount].eid_str, 00942 sizeof(trans->parent->dr[trans->parent->respcount].eid_str), 00943 &ies->answers[x]->eid); 00944 ast_copy_string(trans->parent->dr[trans->parent->respcount].dest, (char *)ies->answers[x]->data, 00945 sizeof(trans->parent->dr[trans->parent->respcount].dest)); 00946 ast_copy_string(trans->parent->dr[trans->parent->respcount].tech, tech2str(ies->answers[x]->protocol), 00947 sizeof(trans->parent->dr[trans->parent->respcount].tech)); 00948 trans->parent->respcount++; 00949 ast_clear_flag_nonstd(trans->parent->hmd, DUNDI_HINT_DONT_ASK); 00950 } else if (trans->parent->dr[z].weight > ies->answers[x]->weight) { 00951 /* Update weight if appropriate */ 00952 trans->parent->dr[z].weight = ies->answers[x]->weight; 00953 } 00954 } else 00955 ast_log(LOG_NOTICE, "Dropping excessive answers in precache for %s@%s\n", 00956 trans->parent->number, trans->parent->dcontext); 00957 00958 } 00959 /* Save all the results (if any) we had. Even if no results, still cache lookup. */ 00960 cache_save(&trans->them_eid, trans->parent, 0, 0, ies->expiration, 1); 00961 if (ies->hint) 00962 cache_save_hint(&trans->them_eid, trans->parent, ies->hint, ies->expiration); 00963 00964 totallen = sizeof(struct dundi_query_state); 00965 /* Count matching map entries */ 00966 mapcount = 0; 00967 cur = mappings; 00968 while(cur) { 00969 if (!strcasecmp(cur->dcontext, ccontext)) 00970 mapcount++; 00971 cur = cur->next; 00972 } 00973 00974 /* If no maps, return -1 immediately */ 00975 if (!mapcount) 00976 return -1; 00977 00978 if (ies->eidcount > 1) { 00979 /* Since it is a requirement that the first EID is the authenticating host 00980 and the last EID is the root, it is permissible that the first and last EID 00981 could be the same. In that case, we should go ahead copy only the "root" section 00982 since we will not need it for authentication. */ 00983 if (!dundi_eid_cmp(ies->eids[0], ies->eids[ies->eidcount - 1])) 00984 skipfirst = 1; 00985 } 00986 00987 /* Prepare to run a query and then propagate that as necessary */ 00988 totallen += mapcount * sizeof(struct dundi_mapping); 00989 totallen += (ies->eidcount - skipfirst) * sizeof(dundi_eid); 00990 st = malloc(totallen); 00991 if (st) { 00992 memset(st, 0, totallen); 00993 ast_copy_string(st->called_context, ies->called_context, sizeof(st->called_context)); 00994 ast_copy_string(st->called_number, ies->called_number, sizeof(st->called_number)); 00995 st->trans = trans; 00996 st->ttl = ies->ttl - 1; 00997 st->nocache = ies->cbypass; 00998 if (st->ttl < 0) 00999 st->ttl = 0; 01000 s = st->fluffy; 01001 for (x=skipfirst;ies->eids[x];x++) { 01002 st->eids[x-skipfirst] = (dundi_eid *)s; 01003 *st->eids[x-skipfirst] = *ies->eids[x]; 01004 st->directs[x-skipfirst] = ies->eid_direct[x]; 01005 s += sizeof(dundi_eid); 01006 } 01007 /* Append mappings */ 01008 x = 0; 01009 st->maps = (struct dundi_mapping *)s; 01010 cur = mappings; 01011 while(cur) { 01012 if (!strcasecmp(cur->dcontext, ccontext)) { 01013 if (x < mapcount) { 01014 st->maps[x] = *cur; 01015 st->maps[x].next = NULL; 01016 x++; 01017 } 01018 } 01019 cur = cur->next; 01020 } 01021 st->nummaps = mapcount; 01022 ast_log(LOG_DEBUG, "Forwarding precache for '%s@%s'!\n", ies->called_number, ies->called_context); 01023 pthread_attr_init(&attr); 01024 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 01025 trans->thread = 1; 01026 if (ast_pthread_create(&lookupthread, &attr, dundi_precache_thread, st)) { 01027 trans->thread = 0; 01028 ast_log(LOG_WARNING, "Unable to create thread!\n"); 01029 free(st); 01030 memset(&ied, 0, sizeof(ied)); 01031 dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_GENERAL, "Out of threads"); 01032 dundi_send(trans, DUNDI_COMMAND_PRECACHERP, 0, 1, &ied); 01033 return -1; 01034 } 01035 } else { 01036 ast_log(LOG_WARNING, "Out of memory!\n"); 01037 memset(&ied, 0, sizeof(ied)); 01038 dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_GENERAL, "Out of memory"); 01039 dundi_send(trans, DUNDI_COMMAND_PRECACHERP, 0, 1, &ied); 01040 return -1; 01041 } 01042 return 0; 01043 }
static int dundi_query | ( | struct dundi_transaction * | trans | ) | [static] |
Definition at line 3190 of file pbx_dundi.c.
References ast_log(), ast_sched_add(), dundi_transaction::autokillid, dundi_transaction::autokilltimeout, dundi_request::dcontext, do_autokill(), DUNDI_COMMAND_EIDQUERY, DUNDI_DEFAULT_VERSION, dundi_eid_zero(), dundi_ie_append_eid(), dundi_ie_append_short(), dundi_ie_append_str(), DUNDI_IE_CALLED_CONTEXT, DUNDI_IE_EID, DUNDI_IE_REQEID, DUNDI_IE_TTL, DUNDI_IE_VERSION, dundi_send(), dundi_transaction::eidcount, dundi_transaction::eids, LOG_WARNING, dundi_transaction::parent, dundi_request::query_eid, dundi_transaction::ttl, and dundi_transaction::us_eid.
Referenced by query_transactions().
03191 { 03192 struct dundi_ie_data ied; 03193 int x; 03194 if (!trans->parent) { 03195 ast_log(LOG_WARNING, "Tried to query a transaction with no parent?!?\n"); 03196 return -1; 03197 } 03198 memset(&ied, 0, sizeof(ied)); 03199 dundi_ie_append_short(&ied, DUNDI_IE_VERSION, DUNDI_DEFAULT_VERSION); 03200 if (!dundi_eid_zero(&trans->us_eid)) 03201 dundi_ie_append_eid(&ied, DUNDI_IE_EID, &trans->us_eid); 03202 for (x=0;x<trans->eidcount;x++) 03203 dundi_ie_append_eid(&ied, DUNDI_IE_EID, &trans->eids[x]); 03204 dundi_ie_append_eid(&ied, DUNDI_IE_REQEID, &trans->parent->query_eid); 03205 dundi_ie_append_str(&ied, DUNDI_IE_CALLED_CONTEXT, trans->parent->dcontext); 03206 dundi_ie_append_short(&ied, DUNDI_IE_TTL, trans->ttl); 03207 if (trans->autokilltimeout) 03208 trans->autokillid = ast_sched_add(sched, trans->autokilltimeout, do_autokill, trans); 03209 return dundi_send(trans, DUNDI_COMMAND_EIDQUERY, 0, 0, &ied); 03210 }
int dundi_query_eid | ( | struct dundi_entity_info * | dei, | |
const char * | dcontext, | |||
dundi_eid | eid | |||
) |
Retrieve information on a specific EID.
Definition at line 3846 of file pbx_dundi.c.
References dundi_query_eid_internal(), and dundi_ttl.
Referenced by dundi_do_query().
03847 { 03848 dundi_eid *avoid[1] = { NULL, }; 03849 struct dundi_hint_metadata hmd; 03850 memset(&hmd, 0, sizeof(hmd)); 03851 return dundi_query_eid_internal(dei, dcontext, &eid, &hmd, dundi_ttl, 0, avoid); 03852 }
static int dundi_query_eid_internal | ( | struct dundi_entity_info * | dei, | |
const char * | dcontext, | |||
dundi_eid * | eid, | |||
struct dundi_hint_metadata * | hmd, | |||
int | ttl, | |||
int | blockempty, | |||
dundi_eid * | avoid[] | |||
) | [static] |
Definition at line 3799 of file pbx_dundi.c.
References ast_set_flag_nonstd, build_transactions(), dr, DUNDI_FLUFF_TIME, DUNDI_HINT_TTL_EXPIRED, DUNDI_TTL_TIME, optimize_transactions(), and query_transactions().
Referenced by dundi_query_eid(), and dundi_query_thread().
03800 { 03801 int res; 03802 struct dundi_request dr; 03803 dundi_eid *rooteid=NULL; 03804 int x; 03805 int ttlms; 03806 int skipped=0; 03807 int foundcache=0; 03808 struct timeval start; 03809 03810 ttlms = DUNDI_FLUFF_TIME + ttl * DUNDI_TTL_TIME; 03811 03812 for (x=0;avoid[x];x++) 03813 rooteid = avoid[x]; 03814 /* Now perform real check */ 03815 memset(&dr, 0, sizeof(dr)); 03816 dr.hmd = hmd; 03817 dr.dei = dei; 03818 dr.pfds[0] = dr.pfds[1] = -1; 03819 ast_copy_string(dr.dcontext, dcontext ? dcontext : "e164", sizeof(dr.dcontext)); 03820 memcpy(&dr.query_eid, eid, sizeof(dr.query_eid)); 03821 if (rooteid) 03822 dr.root_eid = *rooteid; 03823 /* Create transactions */ 03824 build_transactions(&dr, ttl, 9999, &foundcache, &skipped, blockempty, 0, 0, NULL, avoid, NULL); 03825 03826 /* If no TTL, abort and return 0 now after setting TTL expired hint. Couldn't 03827 do this earlier because we didn't know if we were going to have transactions 03828 or not. */ 03829 if (!ttl) { 03830 ast_set_flag_nonstd(hmd, DUNDI_HINT_TTL_EXPIRED); 03831 return 0; 03832 } 03833 03834 /* Optimize transactions */ 03835 optimize_transactions(&dr, 9999); 03836 /* Actually perform transactions */ 03837 query_transactions(&dr); 03838 /* Wait for transaction to come back */ 03839 start = ast_tvnow(); 03840 while(dr.trans && (ast_tvdiff_ms(ast_tvnow(), start) < ttlms)) 03841 usleep(1); 03842 res = dr.respcount; 03843 return res; 03844 }
static void* dundi_query_thread | ( | void * | data | ) | [static] |
Definition at line 701 of file pbx_dundi.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, dundi_query_state::called_context, dundi_query_state::called_number, country, dept, destroy_trans(), DUNDI_COMMAND_EIDRESPONSE, dundi_eid_cmp(), dundi_eid_to_str(), dundi_ie_append_hint(), dundi_ie_append_str(), DUNDI_IE_COUNTRY, DUNDI_IE_DEPARTMENT, DUNDI_IE_EMAIL, DUNDI_IE_HINT, DUNDI_IE_IPADDR, DUNDI_IE_LOCALITY, DUNDI_IE_ORGANIZATION, DUNDI_IE_PHONE, DUNDI_IE_STATE_PROV, dundi_query_eid_internal(), dundi_send(), dundi_query_state::eids, email, FLAG_DEAD, free, locality, LOG_DEBUG, org, phone, dundi_query_state::reqeid, stateprov, dundi_transaction::thread, dundi_query_state::trans, dundi_query_state::ttl, and dundi_transaction::us_eid.
Referenced by dundi_answer_entity().
00702 { 00703 struct dundi_query_state *st = data; 00704 struct dundi_entity_info dei; 00705 struct dundi_ie_data ied; 00706 struct dundi_hint_metadata hmd; 00707 char eid_str[20]; 00708 int res; 00709 ast_log(LOG_DEBUG, "Whee, looking up '%s@%s' for '%s'\n", st->called_number, st->called_context, 00710 st->eids[0] ? dundi_eid_to_str(eid_str, sizeof(eid_str), st->eids[0]) : "ourselves"); 00711 memset(&ied, 0, sizeof(ied)); 00712 memset(&dei, 0, sizeof(dei)); 00713 memset(&hmd, 0, sizeof(hmd)); 00714 if (!dundi_eid_cmp(&st->trans->us_eid, &st->reqeid)) { 00715 /* Ooh, it's us! */ 00716 ast_log(LOG_DEBUG, "Neat, someone look for us!\n"); 00717 ast_copy_string(dei.orgunit, dept, sizeof(dei.orgunit)); 00718 ast_copy_string(dei.org, org, sizeof(dei.org)); 00719 ast_copy_string(dei.locality, locality, sizeof(dei.locality)); 00720 ast_copy_string(dei.stateprov, stateprov, sizeof(dei.stateprov)); 00721 ast_copy_string(dei.country, country, sizeof(dei.country)); 00722 ast_copy_string(dei.email, email, sizeof(dei.email)); 00723 ast_copy_string(dei.phone, phone, sizeof(dei.phone)); 00724 res = 1; 00725 } else { 00726 /* If we do not have a canonical result, keep looking */ 00727 res = dundi_query_eid_internal(&dei, st->called_context, &st->reqeid, &hmd, st->ttl, 1, st->eids); 00728 } 00729 ast_mutex_lock(&peerlock); 00730 if (ast_test_flag(st->trans, FLAG_DEAD)) { 00731 ast_log(LOG_DEBUG, "Our transaction went away!\n"); 00732 st->trans->thread = 0; 00733 destroy_trans(st->trans, 0); 00734 } else { 00735 if (res) { 00736 dundi_ie_append_str(&ied, DUNDI_IE_DEPARTMENT, dei.orgunit); 00737 dundi_ie_append_str(&ied, DUNDI_IE_ORGANIZATION, dei.org); 00738 dundi_ie_append_str(&ied, DUNDI_IE_LOCALITY, dei.locality); 00739 dundi_ie_append_str(&ied, DUNDI_IE_STATE_PROV, dei.stateprov); 00740 dundi_ie_append_str(&ied, DUNDI_IE_COUNTRY, dei.country); 00741 dundi_ie_append_str(&ied, DUNDI_IE_EMAIL, dei.email); 00742 dundi_ie_append_str(&ied, DUNDI_IE_PHONE, dei.phone); 00743 if (!ast_strlen_zero(dei.ipaddr)) 00744 dundi_ie_append_str(&ied, DUNDI_IE_IPADDR, dei.ipaddr); 00745 } 00746 dundi_ie_append_hint(&ied, DUNDI_IE_HINT, hmd.flags, hmd.exten); 00747 dundi_send(st->trans, DUNDI_COMMAND_EIDRESPONSE, 0, 1, &ied); 00748 st->trans->thread = 0; 00749 } 00750 ast_mutex_unlock(&peerlock); 00751 free(st); 00752 return NULL; 00753 }
static void dundi_reject | ( | struct dundi_hdr * | h, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 382 of file pbx_dundi.c.
References dundi_hdr::cmdresp, dundi_hdr::dtrans, DUNDI_COMMAND_INVALID, dundi_xmit(), dundi_hdr::iseqno, dundi_hdr::oseqno, and dundi_hdr::strans.
Referenced by handle_frame().
00383 { 00384 struct { 00385 struct dundi_packet pack; 00386 struct dundi_hdr hdr; 00387 } tmp; 00388 struct dundi_transaction trans; 00389 /* Never respond to an INVALID with another INVALID */ 00390 if (h->cmdresp == DUNDI_COMMAND_INVALID) 00391 return; 00392 memset(&tmp, 0, sizeof(tmp)); 00393 memset(&trans, 0, sizeof(trans)); 00394 memcpy(&trans.addr, sin, sizeof(trans.addr)); 00395 tmp.hdr.strans = h->dtrans; 00396 tmp.hdr.dtrans = h->strans; 00397 tmp.hdr.iseqno = h->oseqno; 00398 tmp.hdr.oseqno = h->iseqno; 00399 tmp.hdr.cmdresp = DUNDI_COMMAND_INVALID; 00400 tmp.hdr.cmdflags = 0; 00401 tmp.pack.h = (struct dundi_hdr *)tmp.pack.data; 00402 tmp.pack.datalen = sizeof(struct dundi_hdr); 00403 tmp.pack.parent = &trans; 00404 dundi_xmit(&tmp.pack); 00405 }
static int dundi_rexmit | ( | void * | data | ) | [static] |
Definition at line 2967 of file pbx_dundi.c.
References dundi_transaction::addr, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, destroy_trans(), dundi_xmit(), FLAG_ISQUAL, dundi_packet::h, LOG_NOTICE, dundi_hdr::oseqno, dundi_packet::parent, dundi_packet::retrans, dundi_packet::retransid, and dundi_hdr::strans.
Referenced by dundi_send().
02968 { 02969 struct dundi_packet *pack; 02970 char iabuf[INET_ADDRSTRLEN]; 02971 int res; 02972 ast_mutex_lock(&peerlock); 02973 pack = data; 02974 if (pack->retrans < 1) { 02975 pack->retransid = -1; 02976 if (!ast_test_flag(pack->parent, FLAG_ISQUAL)) 02977 ast_log(LOG_NOTICE, "Max retries exceeded to host '%s:%d' msg %d on call %d\n", 02978 ast_inet_ntoa(iabuf, sizeof(iabuf), pack->parent->addr.sin_addr), 02979 ntohs(pack->parent->addr.sin_port), pack->h->oseqno, ntohs(pack->h->strans)); 02980 destroy_trans(pack->parent, 1); 02981 res = 0; 02982 } else { 02983 /* Decrement retransmission, try again */ 02984 pack->retrans--; 02985 dundi_xmit(pack); 02986 res = 1; 02987 } 02988 ast_mutex_unlock(&peerlock); 02989 return res; 02990 }
static int dundi_send | ( | struct dundi_transaction * | trans, | |
int | cmdresp, | |||
int | flags, | |||
int | final, | |||
struct dundi_ie_data * | ied | |||
) | [static] |
Definition at line 2992 of file pbx_dundi.c.
References dundi_transaction::addr, dundi_transaction::aseqno, ast_log(), ast_sched_add(), ast_set_flag, ast_test_flag, dundi_hdr::cmdflags, dundi_hdr::cmdresp, dundi_packet::data, dundi_packet::datalen, dundi_transaction::dtrans, dundi_hdr::dtrans, DUNDI_COMMAND_ACK, DUNDI_COMMAND_DPDISCOVER, DUNDI_COMMAND_DPRESPONSE, DUNDI_COMMAND_EIDQUERY, DUNDI_COMMAND_EIDRESPONSE, DUNDI_COMMAND_FINAL, DUNDI_COMMAND_PRECACHERP, DUNDI_COMMAND_PRECACHERQ, DUNDI_COMMAND_REGREQ, DUNDI_COMMAND_REGRESPONSE, DUNDI_DEFAULT_RETRANS, dundi_eid_to_str(), dundi_encrypt(), dundi_rexmit(), dundi_showframe(), dundi_xmit(), dundidebug, FLAG_ENCRYPT, FLAG_FINAL, free, dundi_packet::h, dundi_hdr::ies, dundi_transaction::iseqno, dundi_hdr::iseqno, LOG_NOTICE, malloc, dundi_packet::next, dundi_transaction::oseqno, dundi_hdr::oseqno, dundi_transaction::packets, dundi_packet::parent, dundi_packet::retrans, dundi_packet::retransid, dundi_transaction::retranstimer, dundi_transaction::strans, dundi_hdr::strans, and dundi_transaction::them_eid.
Referenced by cancel_request(), do_register(), dundi_ack(), dundi_answer_entity(), dundi_answer_query(), dundi_discover(), dundi_lookup_thread(), dundi_precache_thread(), dundi_query(), dundi_query_thread(), handle_command_response(), precache_trans(), and qualify_peer().
02993 { 02994 struct dundi_packet *pack; 02995 int res; 02996 int len; 02997 char eid_str[20]; 02998 len = sizeof(struct dundi_packet) + sizeof(struct dundi_hdr) + (ied ? ied->pos : 0); 02999 /* Reserve enough space for encryption */ 03000 if (ast_test_flag(trans, FLAG_ENCRYPT)) 03001 len += 384; 03002 pack = malloc(len); 03003 if (pack) { 03004 memset(pack, 0, len); 03005 pack->h = (struct dundi_hdr *)(pack->data); 03006 if (cmdresp != DUNDI_COMMAND_ACK) { 03007 pack->retransid = ast_sched_add(sched, trans->retranstimer, dundi_rexmit, pack); 03008 pack->retrans = DUNDI_DEFAULT_RETRANS - 1; 03009 pack->next = trans->packets; 03010 trans->packets = pack; 03011 } 03012 pack->parent = trans; 03013 pack->h->strans = htons(trans->strans); 03014 pack->h->dtrans = htons(trans->dtrans); 03015 pack->h->iseqno = trans->iseqno; 03016 pack->h->oseqno = trans->oseqno; 03017 pack->h->cmdresp = cmdresp; 03018 pack->datalen = sizeof(struct dundi_hdr); 03019 if (ied) { 03020 memcpy(pack->h->ies, ied->buf, ied->pos); 03021 pack->datalen += ied->pos; 03022 } 03023 if (final) { 03024 pack->h->cmdresp |= DUNDI_COMMAND_FINAL; 03025 ast_set_flag(trans, FLAG_FINAL); 03026 } 03027 pack->h->cmdflags = flags; 03028 if (cmdresp != DUNDI_COMMAND_ACK) { 03029 trans->oseqno++; 03030 trans->oseqno = trans->oseqno % 256; 03031 } 03032 trans->aseqno = trans->iseqno; 03033 /* If we have their public key, encrypt */ 03034 if (ast_test_flag(trans, FLAG_ENCRYPT)) { 03035 switch(cmdresp) { 03036 case DUNDI_COMMAND_REGREQ: 03037 case DUNDI_COMMAND_REGRESPONSE: 03038 case DUNDI_COMMAND_DPDISCOVER: 03039 case DUNDI_COMMAND_DPRESPONSE: 03040 case DUNDI_COMMAND_EIDQUERY: 03041 case DUNDI_COMMAND_EIDRESPONSE: 03042 case DUNDI_COMMAND_PRECACHERQ: 03043 case DUNDI_COMMAND_PRECACHERP: 03044 if (dundidebug) 03045 dundi_showframe(pack->h, 2, &trans->addr, pack->datalen - sizeof(struct dundi_hdr)); 03046 res = dundi_encrypt(trans, pack); 03047 break; 03048 default: 03049 res = 0; 03050 } 03051 } else 03052 res = 0; 03053 if (!res) 03054 res = dundi_xmit(pack); 03055 if (res) 03056 ast_log(LOG_NOTICE, "Failed to send packet to '%s'\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &trans->them_eid)); 03057 03058 if (cmdresp == DUNDI_COMMAND_ACK) 03059 free(pack); 03060 return res; 03061 } 03062 return -1; 03063 }
static int dundi_show_entityid | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2575 of file pbx_dundi.c.
References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), dundi_eid_to_str(), global_eid, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02576 { 02577 char eid_str[20]; 02578 if (argc != 3) 02579 return RESULT_SHOWUSAGE; 02580 ast_mutex_lock(&peerlock); 02581 dundi_eid_to_str(eid_str, sizeof(eid_str), &global_eid); 02582 ast_mutex_unlock(&peerlock); 02583 ast_cli(fd, "Global EID for this system is '%s'\n", eid_str); 02584 return RESULT_SUCCESS; 02585 }
static int dundi_show_mappings | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2609 of file pbx_dundi.c.
References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), dundi_flags2str(), FORMAT, FORMAT2, map, mappings, RESULT_SHOWUSAGE, RESULT_SUCCESS, and tech2str().
02610 { 02611 #define FORMAT2 "%-12.12s %-7.7s %-12.12s %-10.10s %-5.5s %-25.25s\n" 02612 #define FORMAT "%-12.12s %-7d %-12.12s %-10.10s %-5.5s %-25.25s\n" 02613 struct dundi_mapping *map; 02614 char fs[256]; 02615 if (argc != 3) 02616 return RESULT_SHOWUSAGE; 02617 ast_mutex_lock(&peerlock); 02618 ast_cli(fd, FORMAT2, "DUNDi Cntxt", "Weight", "Local Cntxt", "Options", "Tech", "Destination"); 02619 for (map = mappings;map;map = map->next) { 02620 ast_cli(fd, FORMAT, map->dcontext, map->weight, 02621 ast_strlen_zero(map->lcontext) ? "<none>" : map->lcontext, 02622 dundi_flags2str(fs, sizeof(fs), map->options), tech2str(map->tech), map->dest); 02623 } 02624 ast_mutex_unlock(&peerlock); 02625 return RESULT_SUCCESS; 02626 #undef FORMAT 02627 #undef FORMAT2 02628 }
static int dundi_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2394 of file pbx_dundi.c.
References dundi_peer::addr, permission::allow, ast_cli(), ast_inet_ntoa(), ast_mutex_lock(), ast_strlen_zero(), dundi_peer::avgms, dundi_eid_to_str(), DUNDI_MODEL_INBOUND, DUNDI_MODEL_OUTBOUND, DUNDI_TIMING_HISTORY, dundi_peer::dynamic, dundi_peer::eid, dundi_peer::include, dundi_peer::inkey, dundi_peer::keypending, dundi_peer::lookups, dundi_peer::lookuptimes, dundi_peer::model, model2str(), permission::name, permission::next, dundi_peer::next, dundi_peer::order, dundi_peer::outkey, peers, dundi_peer::permit, dundi_peer::registerid, and RESULT_SHOWUSAGE.
02395 { 02396 struct dundi_peer *peer; 02397 struct permission *p; 02398 char *order; 02399 char iabuf[INET_ADDRSTRLEN]; 02400 char eid_str[20]; 02401 int x, cnt; 02402 02403 if (argc != 4) 02404 return RESULT_SHOWUSAGE; 02405 ast_mutex_lock(&peerlock); 02406 peer = peers; 02407 while(peer) { 02408 if (!strcasecmp(dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid), argv[3])) 02409 break; 02410 peer = peer->next; 02411 } 02412 if (peer) { 02413 switch(peer->order) { 02414 case 0: 02415 order = "Primary"; 02416 break; 02417 case 1: 02418 order = "Secondary"; 02419 break; 02420 case 2: 02421 order = "Tertiary"; 02422 break; 02423 case 3: 02424 order = "Quartiary"; 02425 break; 02426 default: 02427 order = "Unknown"; 02428 } 02429 ast_cli(fd, "Peer: %s\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid)); 02430 ast_cli(fd, "Model: %s\n", model2str(peer->model)); 02431 ast_cli(fd, "Host: %s\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "<Unspecified>"); 02432 ast_cli(fd, "Dynamic: %s\n", peer->dynamic ? "yes" : "no"); 02433 ast_cli(fd, "KeyPend: %s\n", peer->keypending ? "yes" : "no"); 02434 ast_cli(fd, "Reg: %s\n", peer->registerid < 0 ? "No" : "Yes"); 02435 ast_cli(fd, "In Key: %s\n", ast_strlen_zero(peer->inkey) ? "<None>" : peer->inkey); 02436 ast_cli(fd, "Out Key: %s\n", ast_strlen_zero(peer->outkey) ? "<None>" : peer->outkey); 02437 if (peer->include) { 02438 ast_cli(fd, "Include logic%s:\n", peer->model & DUNDI_MODEL_OUTBOUND ? "" : " (IGNORED)"); 02439 } 02440 p = peer->include; 02441 while(p) { 02442 ast_cli(fd, "-- %s %s\n", p->allow ? "include" : "do not include", p->name); 02443 p = p->next; 02444 } 02445 if (peer->permit) { 02446 ast_cli(fd, "Query logic%s:\n", peer->model & DUNDI_MODEL_INBOUND ? "" : " (IGNORED)"); 02447 } 02448 p = peer->permit; 02449 while(p) { 02450 ast_cli(fd, "-- %s %s\n", p->allow ? "permit" : "deny", p->name); 02451 p = p->next; 02452 } 02453 cnt = 0; 02454 for (x=0;x<DUNDI_TIMING_HISTORY;x++) { 02455 if (peer->lookups[x]) { 02456 if (!cnt) 02457 ast_cli(fd, "Last few query times:\n"); 02458 ast_cli(fd, "-- %d. %s (%d ms)\n", x + 1, peer->lookups[x], peer->lookuptimes[x]); 02459 cnt++; 02460 } 02461 } 02462 if (cnt) 02463 ast_cli(fd, "Average query time: %d ms\n", peer->avgms); 02464 } else 02465 ast_cli(fd, "No such peer '%s'\n", argv[3]); 02466 ast_mutex_unlock(&peerlock); 02467 return RESULT_SUCCESS; 02468 }
static int dundi_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2470 of file pbx_dundi.c.
References dundi_peer::addr, ast_cli(), ast_mutex_lock(), dundi_peer::avgms, FORMAT2, dundi_peer::lastms, dundi_peer::maxms, dundi_peer::next, peers, and RESULT_SHOWUSAGE.
02471 { 02472 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-8.8s %-15.15s\n" 02473 #define FORMAT "%-20.20s %-15.15s %s %-10.10s %-8.8s %-15.15s\n" 02474 struct dundi_peer *peer; 02475 char iabuf[INET_ADDRSTRLEN]; 02476 int registeredonly=0; 02477 char avgms[20]; 02478 char eid_str[20]; 02479 int online_peers = 0; 02480 int offline_peers = 0; 02481 int unmonitored_peers = 0; 02482 int total_peers = 0; 02483 02484 if ((argc != 3) && (argc != 4) && (argc != 5)) 02485 return RESULT_SHOWUSAGE; 02486 if ((argc == 4)) { 02487 if (!strcasecmp(argv[3], "registered")) { 02488 registeredonly = 1; 02489 } else 02490 return RESULT_SHOWUSAGE; 02491 } 02492 ast_mutex_lock(&peerlock); 02493 ast_cli(fd, FORMAT2, "EID", "Host", "Model", "AvgTime", "Status"); 02494 for (peer = peers;peer;peer = peer->next) { 02495 char status[20]; 02496 int print_line = -1; 02497 char srch[2000]; 02498 total_peers++; 02499 if (registeredonly && !peer->addr.sin_addr.s_addr) 02500 continue; 02501 if (peer->maxms) { 02502 if (peer->lastms < 0) { 02503 strcpy(status, "UNREACHABLE"); 02504 offline_peers++; 02505 } 02506 else if (peer->lastms > peer->maxms) { 02507 snprintf(status, sizeof(status), "LAGGED (%d ms)", peer->lastms); 02508 offline_peers++; 02509 } 02510 else if (peer->lastms) { 02511 snprintf(status, sizeof(status), "OK (%d ms)", peer->lastms); 02512 online_peers++; 02513 } 02514 else { 02515 strcpy(status, "UNKNOWN"); 02516 offline_peers++; 02517 } 02518 } else { 02519 strcpy(status, "Unmonitored"); 02520 unmonitored_peers++; 02521 } 02522 if (peer->avgms) 02523 snprintf(avgms, sizeof(avgms), "%d ms", peer->avgms); 02524 else 02525 strcpy(avgms, "Unavail"); 02526 snprintf(srch, sizeof(srch), FORMAT, dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid), 02527 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", 02528 peer->dynamic ? "(D)" : "(S)", model2str(peer->model), avgms, status); 02529 02530 if (argc == 5) { 02531 if (!strcasecmp(argv[3],"include") && strstr(srch,argv[4])) { 02532 print_line = -1; 02533 } else if (!strcasecmp(argv[3],"exclude") && !strstr(srch,argv[4])) { 02534 print_line = 1; 02535 } else if (!strcasecmp(argv[3],"begin") && !strncasecmp(srch,argv[4],strlen(argv[4]))) { 02536 print_line = -1; 02537 } else { 02538 print_line = 0; 02539 } 02540 } 02541 02542 if (print_line) { 02543 ast_cli(fd, FORMAT, dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid), 02544 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", 02545 peer->dynamic ? "(D)" : "(S)", model2str(peer->model), avgms, status); 02546 } 02547 } 02548 ast_cli(fd, "%d dundi peers [%d online, %d offline, %d unmonitored]\n", total_peers, online_peers, offline_peers, unmonitored_peers); 02549 ast_mutex_unlock(&peerlock); 02550 return RESULT_SUCCESS; 02551 #undef FORMAT 02552 #undef FORMAT2 02553 }
static int dundi_show_precache | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2630 of file pbx_dundi.c.
References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), dundi_precache_queue::context, dundi_precache_queue::expiration, FORMAT, FORMAT2, dundi_precache_queue::next, dundi_precache_queue::number, pcq, RESULT_SHOWUSAGE, RESULT_SUCCESS, and s.
02631 { 02632 #define FORMAT2 "%-12.12s %-12.12s %-10.10s\n" 02633 #define FORMAT "%-12.12s %-12.12s %02d:%02d:%02d\n" 02634 struct dundi_precache_queue *qe; 02635 int h,m,s; 02636 time_t now; 02637 02638 if (argc != 3) 02639 return RESULT_SHOWUSAGE; 02640 time(&now); 02641 ast_mutex_lock(&pclock); 02642 ast_cli(fd, FORMAT2, "Number", "Context", "Expiration"); 02643 for (qe = pcq;qe;qe = qe->next) { 02644 s = qe->expiration - now; 02645 h = s / 3600; 02646 s = s % 3600; 02647 m = s / 60; 02648 s = s % 60; 02649 ast_cli(fd, FORMAT, qe->number, qe->context, h,m,s); 02650 } 02651 ast_mutex_unlock(&pclock); 02652 return RESULT_SUCCESS; 02653 #undef FORMAT 02654 #undef FORMAT2 02655 }
static int dundi_show_requests | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2587 of file pbx_dundi.c.
References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), dundi_request::dcontext, dundi_eid_to_str(), dundi_eid_zero(), FORMAT, FORMAT2, dundi_request::maxcount, dundi_request::next, dundi_request::number, requests, dundi_request::respcount, RESULT_SHOWUSAGE, RESULT_SUCCESS, and dundi_request::root_eid.
02588 { 02589 #define FORMAT2 "%-15s %-15s %-15s %-3.3s %-3.3s\n" 02590 #define FORMAT "%-15s %-15s %-15s %-3.3d %-3.3d\n" 02591 struct dundi_request *req; 02592 char eidstr[20]; 02593 if (argc != 3) 02594 return RESULT_SHOWUSAGE; 02595 ast_mutex_lock(&peerlock); 02596 ast_cli(fd, FORMAT2, "Number", "Context", "Root", "Max", "Rsp"); 02597 for (req = requests;req;req = req->next) { 02598 ast_cli(fd, FORMAT, req->number, req->dcontext, 02599 dundi_eid_zero(&req->root_eid) ? "<unspecified>" : dundi_eid_to_str(eidstr, sizeof(eidstr), &req->root_eid), req->maxcount, req->respcount); 02600 } 02601 ast_mutex_unlock(&peerlock); 02602 return RESULT_SUCCESS; 02603 #undef FORMAT 02604 #undef FORMAT2 02605 }
static int dundi_show_trans | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2555 of file pbx_dundi.c.
References dundi_transaction::addr, dundi_transaction::allnext, alltrans, dundi_transaction::aseqno, ast_cli(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), dundi_transaction::dtrans, FORMAT, FORMAT2, dundi_transaction::iseqno, dundi_transaction::oseqno, RESULT_SHOWUSAGE, RESULT_SUCCESS, and dundi_transaction::strans.
02556 { 02557 #define FORMAT2 "%-22.22s %-5.5s %-5.5s %-3.3s %-3.3s %-3.3s\n" 02558 #define FORMAT "%-16.16s:%5d %-5.5d %-5.5d %-3.3d %-3.3d %-3.3d\n" 02559 struct dundi_transaction *trans; 02560 char iabuf[INET_ADDRSTRLEN]; 02561 if (argc != 3) 02562 return RESULT_SHOWUSAGE; 02563 ast_mutex_lock(&peerlock); 02564 ast_cli(fd, FORMAT2, "Remote", "Src", "Dst", "Tx", "Rx", "Ack"); 02565 for (trans = alltrans;trans;trans = trans->allnext) { 02566 ast_cli(fd, FORMAT, ast_inet_ntoa(iabuf, sizeof(iabuf), trans->addr.sin_addr), 02567 ntohs(trans->addr.sin_port), trans->strans, trans->dtrans, trans->oseqno, trans->iseqno, trans->aseqno); 02568 } 02569 ast_mutex_unlock(&peerlock); 02570 return RESULT_SUCCESS; 02571 #undef FORMAT 02572 #undef FORMAT2 02573 }
static int dundi_xmit | ( | struct dundi_packet * | pack | ) | [static] |
Definition at line 2808 of file pbx_dundi.c.
References dundi_transaction::addr, ast_inet_ntoa(), ast_log(), dundi_packet::data, dundi_packet::datalen, dundi_showframe(), dundidebug, dundi_packet::h, LOG_WARNING, netsocket, and dundi_packet::parent.
Referenced by dundi_reject(), dundi_rexmit(), and dundi_send().
02809 { 02810 int res; 02811 char iabuf[INET_ADDRSTRLEN]; 02812 if (dundidebug) 02813 dundi_showframe(pack->h, 0, &pack->parent->addr, pack->datalen - sizeof(struct dundi_hdr)); 02814 res = sendto(netsocket, pack->data, pack->datalen, 0, (struct sockaddr *)&pack->parent->addr, sizeof(pack->parent->addr)); 02815 if (res < 0) { 02816 ast_log(LOG_WARNING, "Failed to transmit to '%s:%d': %s\n", 02817 ast_inet_ntoa(iabuf, sizeof(iabuf), pack->parent->addr.sin_addr), 02818 ntohs(pack->parent->addr.sin_port), strerror(errno)); 02819 } 02820 if (res > 0) 02821 res = 0; 02822 return res; 02823 }
static char* dundifunc_read | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 3923 of file pbx_dundi.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, context, dundi_result::dest, dr, DUNDI_FLAG_EXISTS, dundi_lookup(), LOCAL_USER_ACF_ADD, LOCAL_USER_REMOVE, LOG_ERROR, LOG_WARNING, MAX_RESULTS, sort_results(), and dundi_result::tech.
03924 { 03925 char *num; 03926 char *context; 03927 char *opts; 03928 int results; 03929 int x; 03930 int bypass = 0; 03931 struct localuser *u; 03932 struct dundi_result dr[MAX_RESULTS]; 03933 03934 LOCAL_USER_ACF_ADD(u); 03935 03936 buf[0] = '\0'; 03937 03938 if (ast_strlen_zero(data)) { 03939 ast_log(LOG_WARNING, "DUNDILOOKUP requires an argument (number)\n"); 03940 LOCAL_USER_REMOVE(u); 03941 return buf; 03942 } 03943 03944 num = ast_strdupa(data); 03945 if (!num) { 03946 ast_log(LOG_ERROR, "Out of memory!\n"); 03947 LOCAL_USER_REMOVE(u); 03948 return buf; 03949 } 03950 03951 context = strchr(num, '|'); 03952 if (context) { 03953 *context = '\0'; 03954 context++; 03955 opts = strchr(context, '|'); 03956 if (opts) { 03957 *opts = '\0'; 03958 opts++; 03959 if (strchr(opts, 'b')) 03960 bypass = 1; 03961 } 03962 } 03963 03964 if (ast_strlen_zero(context)) 03965 context = "e164"; 03966 03967 results = dundi_lookup(dr, MAX_RESULTS, NULL, context, num, bypass); 03968 if (results > 0) { 03969 sort_results(dr, results); 03970 for (x = 0; x < results; x++) { 03971 if (ast_test_flag(dr + x, DUNDI_FLAG_EXISTS)) { 03972 snprintf(buf, len, "%s/%s", dr[x].tech, dr[x].dest); 03973 break; 03974 } 03975 } 03976 } 03977 03978 LOCAL_USER_REMOVE(u); 03979 03980 return buf; 03981 }
static int encrypt_memcpy | ( | unsigned char * | dst, | |
unsigned char * | src, | |||
int | len, | |||
unsigned char * | iv, | |||
aes_encrypt_ctx * | ecx | |||
) | [static] |
Definition at line 1336 of file pbx_dundi.c.
References aes_encrypt().
Referenced by dundi_encrypt().
01337 { 01338 unsigned char curblock[16]; 01339 int x; 01340 memcpy(curblock, iv, sizeof(curblock)); 01341 while(len > 0) { 01342 for (x=0;x<16;x++) 01343 curblock[x] ^= src[x]; 01344 aes_encrypt(curblock, dst, ecx); 01345 memcpy(curblock, dst, sizeof(curblock)); 01346 dst += 16; 01347 src += 16; 01348 len -= 16; 01349 } 01350 return 0; 01351 }
static struct dundi_peer* find_peer | ( | dundi_eid * | eid | ) | [static] |
Definition at line 489 of file pbx_dundi.c.
References dundi_eid_cmp(), dundi_peer::eid, empty_eid, dundi_peer::next, and peers.
00490 { 00491 struct dundi_peer *cur; 00492 if (!eid) 00493 eid = &empty_eid; 00494 cur = peers; 00495 while(cur) { 00496 if (!dundi_eid_cmp(&cur->eid,eid)) 00497 return cur; 00498 cur = cur->next; 00499 } 00500 return NULL; 00501 }
static struct dundi_transaction* find_transaction | ( | struct dundi_hdr * | hdr, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 336 of file pbx_dundi.c.
References dundi_transaction::addr, dundi_transaction::allnext, alltrans, ast_log(), dundi_hdr::cmdresp, create_transaction(), dundi_transaction::dtrans, dundi_hdr::dtrans, DUNDI_COMMAND_DPDISCOVER, DUNDI_COMMAND_EIDQUERY, DUNDI_COMMAND_ENCRYPT, DUNDI_COMMAND_NULL, DUNDI_COMMAND_PRECACHERQ, DUNDI_COMMAND_REGREQ, inaddrcmp(), LOG_WARNING, dundi_hdr::strans, and dundi_transaction::strans.
Referenced by handle_frame().
00337 { 00338 /* Look for an exact match first */ 00339 struct dundi_transaction *trans; 00340 trans = alltrans; 00341 while(trans) { 00342 if (!inaddrcmp(&trans->addr, sin) && 00343 ((trans->strans == (ntohs(hdr->dtrans) & 32767)) /* Matches our destination */ || 00344 ((trans->dtrans == (ntohs(hdr->strans) & 32767)) && (!hdr->dtrans))) /* We match their destination */) { 00345 if (hdr->strans) 00346 trans->dtrans = ntohs(hdr->strans) & 32767; 00347 break; 00348 } 00349 trans = trans->allnext; 00350 } 00351 if (!trans) { 00352 switch(hdr->cmdresp & 0x7f) { 00353 case DUNDI_COMMAND_DPDISCOVER: 00354 case DUNDI_COMMAND_EIDQUERY: 00355 case DUNDI_COMMAND_PRECACHERQ: 00356 case DUNDI_COMMAND_REGREQ: 00357 case DUNDI_COMMAND_NULL: 00358 case DUNDI_COMMAND_ENCRYPT: 00359 if (hdr->strans) { 00360 /* Create new transaction */ 00361 trans = create_transaction(NULL); 00362 if (trans) { 00363 memcpy(&trans->addr, sin, sizeof(trans->addr)); 00364 trans->dtrans = ntohs(hdr->strans) & 32767; 00365 } else 00366 ast_log(LOG_WARNING, "Out of memory!\n"); 00367 } 00368 break; 00369 default: 00370 break; 00371 } 00372 } 00373 return trans; 00374 }
static int get_trans_id | ( | void | ) | [static] |
Definition at line 454 of file pbx_dundi.c.
Referenced by create_transaction(), and reset_transaction().
00455 { 00456 struct dundi_transaction *t; 00457 int stid = (rand() % 32766) + 1; 00458 int tid = stid; 00459 do { 00460 t = alltrans; 00461 while(t) { 00462 if (t->strans == tid) 00463 break; 00464 t = t->allnext; 00465 } 00466 if (!t) 00467 return tid; 00468 tid = (tid % 32766) + 1; 00469 } while (tid != stid); 00470 return 0; 00471 }
static int handle_command_response | ( | struct dundi_transaction * | trans, | |
struct dundi_hdr * | hdr, | |||
int | datalen, | |||
int | encrypted | |||
) | [static] |
Definition at line 1514 of file pbx_dundi.c.
References dundi_peer::addr, dundi_transaction::addr, ast_clear_flag_nonstd, ast_db_put(), ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag_nonstd, ast_strlen_zero(), ast_test_flag, ast_test_flag_nonstd, ast_verbose(), cache_save(), cache_save_hint(), dundi_hdr::cmdresp, dundi_request::dcontext, default_expiration, dundi_result::dest, do_register_expire(), dundi_request::dr, dundi_answer_entity(), dundi_answer_query(), dundi_cache_time, DUNDI_CAUSE_GENERAL, DUNDI_CAUSE_NOAUTH, DUNDI_COMMAND_CANCEL, DUNDI_COMMAND_DPDISCOVER, DUNDI_COMMAND_DPRESPONSE, DUNDI_COMMAND_EIDQUERY, DUNDI_COMMAND_EIDRESPONSE, DUNDI_COMMAND_PRECACHERP, DUNDI_COMMAND_PRECACHERQ, DUNDI_COMMAND_REGREQ, DUNDI_COMMAND_REGRESPONSE, dundi_eid_to_str(), dundi_eid_to_str_short(), DUNDI_HINT_DONT_ASK, DUNDI_HINT_TTL_EXPIRED, DUNDI_HINT_UNAFFECTED, dundi_ie_append_cause(), dundi_ie_append_short(), DUNDI_IE_CAUSE, DUNDI_IE_EXPIRATION, DUNDI_MODEL_INBOUND, dundi_parse_ies(), dundi_prop_precache(), dundi_send(), dundi_peer::dynamic, dundi_peer::eid, dundi_request::expiration, dundi_hint_metadata::exten, find_peer(), FLAG_ENCRYPT, has_permission(), dundi_request::hmd, dundi_hdr::ies, ies, inaddrcmp(), dundi_peer::include, dundi_peer::inkey, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, dundi_request::maxcount, dundi_peer::model, dundi_request::number, option_verbose, dundi_hdr::oseqno, dundi_transaction::parent, dundi_peer::pcmodel, dundi_peer::permit, qualify_peer(), dundi_peer::registerexpire, dundi_request::respcount, tech2str(), dundi_result::techint, dundi_transaction::them_eid, dundi_peer::us_eid, dundi_transaction::us_eid, VERBOSE_PREFIX_3, and dundi_result::weight.
Referenced by handle_frame().
01515 { 01516 /* Handle canonical command / response */ 01517 int final = hdr->cmdresp & 0x80; 01518 int cmd = hdr->cmdresp & 0x7f; 01519 int x,y,z; 01520 int resp; 01521 int res; 01522 int authpass=0; 01523 unsigned char *bufcpy; 01524 struct dundi_ie_data ied; 01525 struct dundi_ies ies; 01526 struct dundi_peer *peer; 01527 char eid_str[20]; 01528 char eid_str2[20]; 01529 memset(&ied, 0, sizeof(ied)); 01530 memset(&ies, 0, sizeof(ies)); 01531 if (datalen) { 01532 bufcpy = alloca(datalen); 01533 if (!bufcpy) 01534 return -1; 01535 /* Make a copy for parsing */ 01536 memcpy(bufcpy, hdr->ies, datalen); 01537 ast_log(LOG_DEBUG, "Got canonical message %d (%d), %d bytes data%s\n", cmd, hdr->oseqno, datalen, final ? " (Final)" : ""); 01538 if (dundi_parse_ies(&ies, bufcpy, datalen) < 0) { 01539 ast_log(LOG_WARNING, "Failed to parse DUNDI information elements!\n"); 01540 return -1; 01541 } 01542 } 01543 switch(cmd) { 01544 case DUNDI_COMMAND_DPDISCOVER: 01545 case DUNDI_COMMAND_EIDQUERY: 01546 case DUNDI_COMMAND_PRECACHERQ: 01547 if (cmd == DUNDI_COMMAND_EIDQUERY) 01548 resp = DUNDI_COMMAND_EIDRESPONSE; 01549 else if (cmd == DUNDI_COMMAND_PRECACHERQ) 01550 resp = DUNDI_COMMAND_PRECACHERP; 01551 else 01552 resp = DUNDI_COMMAND_DPRESPONSE; 01553 /* A dialplan or entity discover -- qualify by highest level entity */ 01554 peer = find_peer(ies.eids[0]); 01555 if (!peer) { 01556 dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, NULL); 01557 dundi_send(trans, resp, 0, 1, &ied); 01558 } else { 01559 int hasauth = 0; 01560 trans->us_eid = peer->us_eid; 01561 if (strlen(peer->inkey)) { 01562 hasauth = encrypted; 01563 } else 01564 hasauth = 1; 01565 if (hasauth) { 01566 /* Okay we're authentiated and all, now we check if they're authorized */ 01567 if (!ies.called_context) 01568 ies.called_context = "e164"; 01569 if (cmd == DUNDI_COMMAND_EIDQUERY) { 01570 res = dundi_answer_entity(trans, &ies, ies.called_context); 01571 } else { 01572 if (ast_strlen_zero(ies.called_number)) { 01573 /* They're not permitted to access that context */ 01574 dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_GENERAL, "Invalid or missing number/entity"); 01575 dundi_send(trans, resp, 0, 1, &ied); 01576 } else if ((cmd == DUNDI_COMMAND_DPDISCOVER) && 01577 (peer->model & DUNDI_MODEL_INBOUND) && 01578 has_permission(peer->permit, ies.called_context)) { 01579 res = dundi_answer_query(trans, &ies, ies.called_context); 01580 if (res < 0) { 01581 /* There is no such dundi context */ 01582 dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, "Unsupported DUNDI Context"); 01583 dundi_send(trans, resp, 0, 1, &ied); 01584 } 01585 } else if ((cmd = DUNDI_COMMAND_PRECACHERQ) && 01586 (peer->pcmodel & DUNDI_MODEL_INBOUND) && 01587 has_permission(peer->include, ies.called_context)) { 01588 res = dundi_prop_precache(trans, &ies, ies.called_context); 01589 if (res < 0) { 01590 /* There is no such dundi context */ 01591 dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, "Unsupported DUNDI Context"); 01592 dundi_send(trans, resp, 0, 1, &ied); 01593 } 01594 } else { 01595 /* They're not permitted to access that context */ 01596 dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, "Permission to context denied"); 01597 dundi_send(trans, resp, 0, 1, &ied); 01598 } 01599 } 01600 } else { 01601 /* They're not permitted to access that context */ 01602 dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, "Unencrypted responses not permitted"); 01603 dundi_send(trans, resp, 0, 1, &ied); 01604 } 01605 } 01606 break; 01607 case DUNDI_COMMAND_REGREQ: 01608 /* A register request -- should only have one entity */ 01609 peer = find_peer(ies.eids[0]); 01610 if (!peer || !peer->dynamic) { 01611 dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, NULL); 01612 dundi_send(trans, DUNDI_COMMAND_REGRESPONSE, 0, 1, &ied); 01613 } else { 01614 int hasauth = 0; 01615 trans->us_eid = peer->us_eid; 01616 if (!ast_strlen_zero(peer->inkey)) { 01617 hasauth = encrypted; 01618 } else 01619 hasauth = 1; 01620 if (hasauth) { 01621 int expire = default_expiration; 01622 char iabuf[INET_ADDRSTRLEN]; 01623 char data[256]; 01624 int needqual = 0; 01625 if (peer->registerexpire > -1) 01626 ast_sched_del(sched, peer->registerexpire); 01627 peer->registerexpire = ast_sched_add(sched, (expire + 10) * 1000, do_register_expire, peer); 01628 ast_inet_ntoa(iabuf, sizeof(iabuf), trans->addr.sin_addr); 01629 snprintf(data, sizeof(data), "%s:%d:%d", iabuf, ntohs(trans->addr.sin_port), expire); 01630 ast_db_put("dundi/dpeers", dundi_eid_to_str_short(eid_str, sizeof(eid_str), &peer->eid), data); 01631 if (inaddrcmp(&peer->addr, &trans->addr)) { 01632 if (option_verbose > 2) 01633 ast_verbose(VERBOSE_PREFIX_3 "Registered DUNDi peer '%s' at '%s:%d'\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid), iabuf, ntohs(trans->addr.sin_port)); 01634 needqual = 1; 01635 } 01636 01637 memcpy(&peer->addr, &trans->addr, sizeof(peer->addr)); 01638 dundi_ie_append_short(&ied, DUNDI_IE_EXPIRATION, default_expiration); 01639 dundi_send(trans, DUNDI_COMMAND_REGRESPONSE, 0, 1, &ied); 01640 if (needqual) 01641 qualify_peer(peer, 1); 01642 } 01643 } 01644 break; 01645 case DUNDI_COMMAND_DPRESPONSE: 01646 /* A dialplan response, lets see what we got... */ 01647 if (ies.cause < 1) { 01648 /* Success of some sort */ 01649 ast_log(LOG_DEBUG, "Looks like success of some sort (%d), %d answers\n", ies.cause, ies.anscount); 01650 if (ast_test_flag(trans, FLAG_ENCRYPT)) { 01651 authpass = encrypted; 01652 } else 01653 authpass = 1; 01654 if (authpass) { 01655 /* Pass back up answers */ 01656 if (trans->parent && trans->parent->dr) { 01657 y = trans->parent->respcount; 01658 for (x=0;x<ies.anscount;x++) { 01659 if (trans->parent->respcount < trans->parent->maxcount) { 01660 /* Make sure it's not already there */ 01661 for (z=0;z<trans->parent->respcount;z++) { 01662 if ((trans->parent->dr[z].techint == ies.answers[x]->protocol) && 01663 !strcmp(trans->parent->dr[z].dest, (char *)ies.answers[x]->data)) 01664 break; 01665 } 01666 if (z == trans->parent->respcount) { 01667 /* Copy into parent responses */ 01668 trans->parent->dr[trans->parent->respcount].flags = ntohs(ies.answers[x]->flags); 01669 trans->parent->dr[trans->parent->respcount].techint = ies.answers[x]->protocol; 01670 trans->parent->dr[trans->parent->respcount].weight = ntohs(ies.answers[x]->weight); 01671 trans->parent->dr[trans->parent->respcount].eid = ies.answers[x]->eid; 01672 if (ies.expiration > 0) 01673 trans->parent->dr[trans->parent->respcount].expiration = ies.expiration; 01674 else 01675 trans->parent->dr[trans->parent->respcount].expiration = dundi_cache_time; 01676 dundi_eid_to_str(trans->parent->dr[trans->parent->respcount].eid_str, 01677 sizeof(trans->parent->dr[trans->parent->respcount].eid_str), 01678 &ies.answers[x]->eid); 01679 ast_copy_string(trans->parent->dr[trans->parent->respcount].dest, (char *)ies.answers[x]->data, 01680 sizeof(trans->parent->dr[trans->parent->respcount].dest)); 01681 ast_copy_string(trans->parent->dr[trans->parent->respcount].tech, tech2str(ies.answers[x]->protocol), 01682 sizeof(trans->parent->dr[trans->parent->respcount].tech)); 01683 trans->parent->respcount++; 01684 ast_clear_flag_nonstd(trans->parent->hmd, DUNDI_HINT_DONT_ASK); 01685 } else if (trans->parent->dr[z].weight > ies.answers[x]->weight) { 01686 /* Update weight if appropriate */ 01687 trans->parent->dr[z].weight = ies.answers[x]->weight; 01688 } 01689 } else 01690 ast_log(LOG_NOTICE, "Dropping excessive answers to request for %s@%s\n", 01691 trans->parent->number, trans->parent->dcontext); 01692 } 01693 /* Save all the results (if any) we had. Even if no results, still cache lookup. Let 01694 the cache know if this request was unaffected by our entity list. */ 01695 cache_save(&trans->them_eid, trans->parent, y, 01696 ies.hint ? ast_test_flag_nonstd(ies.hint, htons(DUNDI_HINT_UNAFFECTED)) : 0, ies.expiration, 0); 01697 if (ies.hint) { 01698 cache_save_hint(&trans->them_eid, trans->parent, ies.hint, ies.expiration); 01699 if (ast_test_flag_nonstd(ies.hint, htons(DUNDI_HINT_TTL_EXPIRED))) 01700 ast_set_flag_nonstd(trans->parent->hmd, DUNDI_HINT_TTL_EXPIRED); 01701 if (ast_test_flag_nonstd(ies.hint, htons(DUNDI_HINT_DONT_ASK))) { 01702 if (strlen((char *)ies.hint->data) > strlen(trans->parent->hmd->exten)) { 01703 ast_copy_string(trans->parent->hmd->exten, (char *)ies.hint->data, 01704 sizeof(trans->parent->hmd->exten)); 01705 } 01706 } else { 01707 ast_clear_flag_nonstd(trans->parent->hmd, DUNDI_HINT_DONT_ASK); 01708 } 01709 } 01710 if (ies.expiration > 0) { 01711 if (trans->parent->expiration > ies.expiration) { 01712 trans->parent->expiration = ies.expiration; 01713 } 01714 } 01715 } 01716 /* Close connection if not final */ 01717 if (!final) 01718 dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, NULL); 01719 } 01720 01721 } else { 01722 /* Auth failure, check for data */ 01723 if (!final) { 01724 /* Cancel if they didn't already */ 01725 dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, NULL); 01726 } 01727 } 01728 break; 01729 case DUNDI_COMMAND_EIDRESPONSE: 01730 /* A dialplan response, lets see what we got... */ 01731 if (ies.cause < 1) { 01732 /* Success of some sort */ 01733 ast_log(LOG_DEBUG, "Looks like success of some sort (%d)\n", ies.cause); 01734 if (ast_test_flag(trans, FLAG_ENCRYPT)) { 01735 authpass = encrypted; 01736 } else 01737 authpass = 1; 01738 if (authpass) { 01739 /* Pass back up answers */ 01740 if (trans->parent && trans->parent->dei && ies.q_org) { 01741 if (!trans->parent->respcount) { 01742 trans->parent->respcount++; 01743 if (ies.q_dept) 01744 ast_copy_string(trans->parent->dei->orgunit, ies.q_dept, sizeof(trans->parent->dei->orgunit)); 01745 if (ies.q_org) 01746 ast_copy_string(trans->parent->dei->org, ies.q_org, sizeof(trans->parent->dei->org)); 01747 if (ies.q_locality) 01748 ast_copy_string(trans->parent->dei->locality, ies.q_locality, sizeof(trans->parent->dei->locality)); 01749 if (ies.q_stateprov) 01750 ast_copy_string(trans->parent->dei->stateprov, ies.q_stateprov, sizeof(trans->parent->dei->stateprov)); 01751 if (ies.q_country) 01752 ast_copy_string(trans->parent->dei->country, ies.q_country, sizeof(trans->parent->dei->country)); 01753 if (ies.q_email) 01754 ast_copy_string(trans->parent->dei->email, ies.q_email, sizeof(trans->parent->dei->email)); 01755 if (ies.q_phone) 01756 ast_copy_string(trans->parent->dei->phone, ies.q_phone, sizeof(trans->parent->dei->phone)); 01757 if (ies.q_ipaddr) 01758 ast_copy_string(trans->parent->dei->ipaddr, ies.q_ipaddr, sizeof(trans->parent->dei->ipaddr)); 01759 if (!dundi_eid_cmp(&trans->them_eid, &trans->parent->query_eid)) { 01760 /* If it's them, update our address */ 01761 ast_inet_ntoa(trans->parent->dei->ipaddr, sizeof(trans->parent->dei->ipaddr), 01762 trans->addr.sin_addr); 01763 } 01764 } 01765 if (ies.hint) { 01766 if (ast_test_flag_nonstd(ies.hint, htons(DUNDI_HINT_TTL_EXPIRED))) 01767 ast_set_flag_nonstd(trans->parent->hmd, DUNDI_HINT_TTL_EXPIRED); 01768 } 01769 } 01770 /* Close connection if not final */ 01771 if (!final) 01772 dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, NULL); 01773 } 01774 01775 } else { 01776 /* Auth failure, check for data */ 01777 if (!final) { 01778 /* Cancel if they didn't already */ 01779 dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, NULL); 01780 } 01781 } 01782 break; 01783 case DUNDI_COMMAND_REGRESPONSE: 01784 /* A dialplan response, lets see what we got... */ 01785 if (ies.cause < 1) { 01786 int hasauth; 01787 /* Success of some sort */ 01788 if (ast_test_flag(trans, FLAG_ENCRYPT)) { 01789 hasauth = encrypted; 01790 } else 01791 hasauth = 1; 01792 01793 if (!hasauth) { 01794 ast_log(LOG_NOTICE, "Reponse to register not authorized!\n"); 01795 if (!final) { 01796 dundi_ie_append_cause(&ied, DUNDI_IE_CAUSE, DUNDI_CAUSE_NOAUTH, "Improper signature in answer"); 01797 dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, &ied); 01798 } 01799 } else { 01800 ast_log(LOG_DEBUG, "Yay, we've registered as '%s' to '%s'\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &trans->us_eid), 01801 dundi_eid_to_str(eid_str2, sizeof(eid_str2), &trans->them_eid)); 01802 /* Close connection if not final */ 01803 if (!final) 01804 dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, NULL); 01805 } 01806 } else { 01807 /* Auth failure, cancel if they didn't for some reason */ 01808 if (!final) { 01809 dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, NULL); 01810 } 01811 } 01812 break; 01813 case DUNDI_COMMAND_INVALID: 01814 case DUNDI_COMMAND_NULL: 01815 case DUNDI_COMMAND_PRECACHERP: 01816 /* Do nothing special */ 01817 if (!final) 01818 dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, NULL); 01819 break; 01820 case DUNDI_COMMAND_ENCREJ: 01821 if ((ast_test_flag(trans, FLAG_SENDFULLKEY)) || !trans->lasttrans || !(peer = find_peer(&trans->them_eid))) { 01822 /* No really, it's over at this point */ 01823 if (!final) 01824 dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, NULL); 01825 } else { 01826 /* Send with full key */ 01827 ast_set_flag(trans, FLAG_SENDFULLKEY); 01828 if (final) { 01829 /* Ooops, we got a final message, start by sending ACK... */ 01830 dundi_ack(trans, hdr->cmdresp & 0x80); 01831 trans->aseqno = trans->iseqno; 01832 /* Now, we gotta create a new transaction */ 01833 if (!reset_transaction(trans)) { 01834 /* Make sure handle_frame doesn't destroy us */ 01835 hdr->cmdresp &= 0x7f; 01836 /* Parse the message we transmitted */ 01837 memset(&ies, 0, sizeof(ies)); 01838 dundi_parse_ies(&ies, trans->lasttrans->h->ies, trans->lasttrans->datalen - sizeof(struct dundi_hdr)); 01839 /* Reconstruct outgoing encrypted packet */ 01840 memset(&ied, 0, sizeof(ied)); 01841 dundi_ie_append_eid(&ied, DUNDI_IE_EID, &trans->us_eid); 01842 dundi_ie_append_raw(&ied, DUNDI_IE_SHAREDKEY, peer->txenckey, 128); 01843 dundi_ie_append_raw(&ied, DUNDI_IE_SIGNATURE, peer->txenckey + 128, 128); 01844 if (ies.encblock) 01845 dundi_ie_append_encdata(&ied, DUNDI_IE_ENCDATA, ies.encblock->iv, ies.encblock->encdata, ies.enclen); 01846 dundi_send(trans, DUNDI_COMMAND_ENCRYPT, 0, trans->lasttrans->h->cmdresp & 0x80, &ied); 01847 peer->sentfullkey = 1; 01848 } 01849 } 01850 } 01851 break; 01852 case DUNDI_COMMAND_ENCRYPT: 01853 if (!encrypted) { 01854 /* No nested encryption! */ 01855 if ((trans->iseqno == 1) && !trans->oseqno) { 01856 if (!ies.eids[0] || !(peer = find_peer(ies.eids[0])) || 01857 ((!ies.encsharedkey || !ies.encsig) && !ies.keycrc32) || 01858 (check_key(peer, ies.encsharedkey, ies.encsig, ies.keycrc32) < 1)) { 01859 if (!final) { 01860 dundi_send(trans, DUNDI_COMMAND_ENCREJ, 0, 1, NULL); 01861 } 01862 break; 01863 } 01864 apply_peer(trans, peer); 01865 /* Key passed, use new contexts for this session */ 01866 trans->ecx = peer->them_ecx; 01867 trans->dcx = peer->them_dcx; 01868 } 01869 if (ast_test_flag(trans, FLAG_ENCRYPT) && ies.encblock && ies.enclen) { 01870 struct dundi_hdr *dhdr; 01871 unsigned char decoded[MAX_PACKET_SIZE]; 01872 int ddatalen; 01873 ddatalen = sizeof(decoded); 01874 dhdr = dundi_decrypt(trans, decoded, &ddatalen, hdr, ies.encblock, ies.enclen); 01875 if (dhdr) { 01876 /* Handle decrypted response */ 01877 if (dundidebug) 01878 dundi_showframe(dhdr, 3, &trans->addr, ddatalen - sizeof(struct dundi_hdr)); 01879 handle_command_response(trans, dhdr, ddatalen - sizeof(struct dundi_hdr), 1); 01880 /* Carry back final flag */ 01881 hdr->cmdresp |= dhdr->cmdresp & 0x80; 01882 break; 01883 } else 01884 ast_log(LOG_DEBUG, "Ouch, decrypt failed :(\n"); 01885 } 01886 } 01887 if (!final) { 01888 /* Turn off encryption */ 01889 ast_clear_flag(trans, FLAG_ENCRYPT); 01890 dundi_send(trans, DUNDI_COMMAND_ENCREJ, 0, 1, NULL); 01891 } 01892 break; 01893 default: 01894 /* Send unknown command if we don't know it, with final flag IFF it's the 01895 first command in the dialog and only if we haven't recieved final notification */ 01896 if (!final) { 01897 dundi_ie_append_byte(&ied, DUNDI_IE_UNKNOWN, cmd); 01898 dundi_send(trans, DUNDI_COMMAND_UNKNOWN, 0, !hdr->oseqno, &ied); 01899 } 01900 } 01901 return 0; 01902 }
static int handle_frame | ( | struct dundi_hdr * | h, | |
struct sockaddr_in * | sin, | |||
int | datalen | |||
) | [static] |
Definition at line 1941 of file pbx_dundi.c.
References ack_trans(), dundi_transaction::aseqno, ast_log(), ast_test_flag, dundi_hdr::cmdresp, destroy_packets(), destroy_trans(), dundi_ack(), DUNDI_COMMAND_ACK, dundi_reject(), find_transaction(), FLAG_FINAL, handle_command_response(), dundi_hdr::iseqno, dundi_transaction::iseqno, dundi_transaction::lasttrans, LOG_DEBUG, dundi_transaction::oiseqno, and dundi_hdr::oseqno.
Referenced by socket_read().
01942 { 01943 struct dundi_transaction *trans; 01944 trans = find_transaction(h, sin); 01945 if (!trans) { 01946 dundi_reject(h, sin); 01947 return 0; 01948 } 01949 /* Got a transaction, see where this header fits in */ 01950 if (h->oseqno == trans->iseqno) { 01951 /* Just what we were looking for... Anything but ack increments iseqno */ 01952 if (ack_trans(trans, h->iseqno) && ast_test_flag(trans, FLAG_FINAL)) { 01953 /* If final, we're done */ 01954 destroy_trans(trans, 0); 01955 return 0; 01956 } 01957 if (h->cmdresp != DUNDI_COMMAND_ACK) { 01958 trans->oiseqno = trans->iseqno; 01959 trans->iseqno++; 01960 handle_command_response(trans, h, datalen, 0); 01961 } 01962 if (trans->aseqno != trans->iseqno) { 01963 dundi_ack(trans, h->cmdresp & 0x80); 01964 trans->aseqno = trans->iseqno; 01965 } 01966 /* Delete any saved last transmissions */ 01967 destroy_packets(trans->lasttrans); 01968 trans->lasttrans = NULL; 01969 if (h->cmdresp & 0x80) { 01970 /* Final -- destroy now */ 01971 destroy_trans(trans, 0); 01972 } 01973 } else if (h->oseqno == trans->oiseqno) { 01974 /* Last incoming sequence number -- send ACK without processing */ 01975 dundi_ack(trans, 0); 01976 } else { 01977 /* Out of window -- simply drop */ 01978 ast_log(LOG_DEBUG, "Dropping packet out of window!\n"); 01979 } 01980 return 0; 01981 }
static int has_permission | ( | struct permission * | ps, | |
char * | cont | |||
) | [static] |
Definition at line 294 of file pbx_dundi.c.
References permission::allow, permission::name, and permission::next.
Referenced by build_transactions(), dundi_ie_append_eid_appropriately(), handle_command_response(), and optimize_transactions().
00295 { 00296 int res=0; 00297 while(ps) { 00298 if (!strcasecmp(ps->name, "all") || !strcasecmp(ps->name, cont)) 00299 res = ps->allow; 00300 ps = ps->next; 00301 } 00302 return res; 00303 }
char* key | ( | void | ) |
Returns the ASTERISK_GPL_KEY.
This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 4828 of file pbx_dundi.c.
References ASTERISK_GPL_KEY.
04829 { 04830 return ASTERISK_GPL_KEY; 04831 }
int load_module | ( | void | ) |
Initialize the module.
Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 4740 of file pbx_dundi.c.
References app, ast_cli_register(), ast_custom_function_register(), ast_inet_ntoa(), ast_log(), ast_register_application(), ast_register_switch(), ast_verbose(), cli_debug, cli_flush, cli_lookup, cli_no_debug, cli_no_store_history, cli_precache, cli_queryeid, cli_show_entityid, cli_show_mappings, cli_show_peer, cli_show_peers, cli_show_precache, cli_show_requests, cli_show_trans, cli_store_history, descrip, dundi_debug_output(), dundi_error_output(), dundi_function, dundi_lookup_exec(), DUNDI_PORT, dundi_set_error(), dundi_set_output(), dundi_switch, io, io_context_create(), LOG_ERROR, LOG_WARNING, netsocket, option_verbose, sched_context_create(), set_config(), start_network_thread(), synopsis, tos, and VERBOSE_PREFIX_2.
04741 { 04742 int res = 0; 04743 struct sockaddr_in sin; 04744 char iabuf[INET_ADDRSTRLEN]; 04745 04746 dundi_set_output(dundi_debug_output); 04747 dundi_set_error(dundi_error_output); 04748 04749 sin.sin_family = AF_INET; 04750 sin.sin_port = ntohs(DUNDI_PORT); 04751 sin.sin_addr.s_addr = INADDR_ANY; 04752 04753 /* Make a UDP socket */ 04754 io = io_context_create(); 04755 sched = sched_context_create(); 04756 04757 if (!io || !sched) { 04758 ast_log(LOG_ERROR, "Out of memory\n"); 04759 return -1; 04760 } 04761 04762 set_config("dundi.conf",&sin); 04763 04764 netsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); 04765 04766 if (netsocket < 0) { 04767 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 04768 return -1; 04769 } 04770 if (bind(netsocket,(struct sockaddr *)&sin, sizeof(sin))) { 04771 ast_log(LOG_ERROR, "Unable to bind to %s port %d: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port), strerror(errno)); 04772 return -1; 04773 } 04774 04775 if (option_verbose > 1) 04776 ast_verbose(VERBOSE_PREFIX_2 "Using TOS bits %d\n", tos); 04777 04778 if (setsockopt(netsocket, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) 04779 ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos); 04780 04781 res = start_network_thread(); 04782 if (res) { 04783 ast_log(LOG_ERROR, "Unable to start network thread\n"); 04784 close(netsocket); 04785 return -1; 04786 } 04787 04788 if (option_verbose > 1) 04789 ast_verbose(VERBOSE_PREFIX_2 "DUNDi Ready and Listening on %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 04790 04791 ast_cli_register(&cli_debug); 04792 ast_cli_register(&cli_store_history); 04793 ast_cli_register(&cli_flush); 04794 ast_cli_register(&cli_no_debug); 04795 ast_cli_register(&cli_no_store_history); 04796 ast_cli_register(&cli_show_peers); 04797 ast_cli_register(&cli_show_entityid); 04798 ast_cli_register(&cli_show_trans); 04799 ast_cli_register(&cli_show_requests); 04800 ast_cli_register(&cli_show_mappings); 04801 ast_cli_register(&cli_show_precache); 04802 ast_cli_register(&cli_show_peer); 04803 ast_cli_register(&cli_lookup); 04804 ast_cli_register(&cli_precache); 04805 ast_cli_register(&cli_queryeid); 04806 if (ast_register_switch(&dundi_switch)) 04807 ast_log(LOG_ERROR, "Unable to register DUNDi switch\n"); 04808 ast_register_application(app, dundi_lookup_exec, synopsis, descrip); 04809 ast_custom_function_register(&dundi_function); 04810 04811 return res; 04812 }
static void load_password | ( | void | ) | [static] |
Definition at line 2039 of file pbx_dundi.c.
References ast_db_get(), build_secret(), cursecret, DUNDI_SECRET_TIME, last, rotatetime, save_secret(), and secretpath.
Referenced by set_config().
02040 { 02041 char *current=NULL; 02042 char *last=NULL; 02043 char tmp[256]; 02044 time_t expired; 02045 02046 ast_db_get(secretpath, "secretexpiry", tmp, sizeof(tmp)); 02047 if (sscanf(tmp, "%d", (int *)&expired) == 1) { 02048 ast_db_get(secretpath, "secret", tmp, sizeof(tmp)); 02049 current = strchr(tmp, ';'); 02050 if (!current) 02051 current = tmp; 02052 else { 02053 *current = '\0'; 02054 current++; 02055 }; 02056 if ((time(NULL) - expired) < 0) { 02057 if ((expired - time(NULL)) > DUNDI_SECRET_TIME) 02058 expired = time(NULL) + DUNDI_SECRET_TIME; 02059 } else if ((time(NULL) - (expired + DUNDI_SECRET_TIME)) < 0) { 02060 last = current; 02061 current = NULL; 02062 } else { 02063 last = NULL; 02064 current = NULL; 02065 } 02066 } 02067 if (current) { 02068 /* Current key is still valid, just setup rotatation properly */ 02069 ast_copy_string(cursecret, current, sizeof(cursecret)); 02070 rotatetime = expired; 02071 } else { 02072 /* Current key is out of date, rotate or eliminate all together */ 02073 build_secret(cursecret, sizeof(cursecret)); 02074 save_secret(cursecret, last); 02075 } 02076 }
static void mark_mappings | ( | void | ) | [static] |
Definition at line 4012 of file pbx_dundi.c.
References ast_mutex_lock(), ast_mutex_unlock(), map, and mappings.
Referenced by set_config().
04013 { 04014 struct dundi_mapping *map; 04015 ast_mutex_lock(&peerlock); 04016 map = mappings; 04017 while(map) { 04018 map->dead = 1; 04019 map = map->next; 04020 } 04021 ast_mutex_unlock(&peerlock); 04022 }
static void mark_peers | ( | void | ) | [static] |
Definition at line 4000 of file pbx_dundi.c.
References ast_mutex_lock(), ast_mutex_unlock(), dundi_peer::dead, dundi_peer::next, and peers.
Referenced by set_config().
04001 { 04002 struct dundi_peer *peer; 04003 ast_mutex_lock(&peerlock); 04004 peer = peers; 04005 while(peer) { 04006 peer->dead = 1; 04007 peer = peer->next; 04008 } 04009 ast_mutex_unlock(&peerlock); 04010 }
static char* model2str | ( | int | model | ) | [static] |
Definition at line 2229 of file pbx_dundi.c.
References DUNDI_MODEL_INBOUND, DUNDI_MODEL_OUTBOUND, and DUNDI_MODEL_SYMMETRIC.
Referenced by dundi_show_peer().
02230 { 02231 switch(model) { 02232 case DUNDI_MODEL_INBOUND: 02233 return "Inbound"; 02234 case DUNDI_MODEL_OUTBOUND: 02235 return "Outbound"; 02236 case DUNDI_MODEL_SYMMETRIC: 02237 return "Symmetric"; 02238 default: 02239 return "Unknown"; 02240 } 02241 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 2095 of file pbx_dundi.c.
References ast_io_add(), AST_IO_IN, ast_io_wait(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_runq(), ast_sched_wait(), check_password(), io, netsocket, and socket_read().
02096 { 02097 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 02098 from the network, and queue them for delivery to the channels */ 02099 int res; 02100 /* Establish I/O callback for socket read */ 02101 ast_io_add(io, netsocket, socket_read, AST_IO_IN, NULL); 02102 for(;;) { 02103 res = ast_sched_wait(sched); 02104 if ((res > 1000) || (res < 0)) 02105 res = 1000; 02106 res = ast_io_wait(io, res); 02107 if (res >= 0) { 02108 ast_mutex_lock(&peerlock); 02109 ast_sched_runq(sched); 02110 ast_mutex_unlock(&peerlock); 02111 } 02112 check_password(); 02113 } 02114 return NULL; 02115 }
static int optimize_transactions | ( | struct dundi_request * | dr, | |
int | order | |||
) | [static] |
Definition at line 3275 of file pbx_dundi.c.
References ast_mutex_lock(), dr, dundi_eid_cmp(), DUNDI_MAX_STACK, dundi_peer::eid, dundi_transaction::eidcount, dundi_transaction::eids, has_permission(), dundi_peer::include, dundi_peer::next, dundi_peer::order, peers, dundi_transaction::them_eid, and dundi_transaction::us_eid.
Referenced by dundi_lookup_internal(), dundi_precache_internal(), and dundi_query_eid_internal().
03276 { 03277 /* Minimize the message propagation through DUNDi by 03278 alerting the network to hops which should be not be considered */ 03279 struct dundi_transaction *trans; 03280 struct dundi_peer *peer; 03281 dundi_eid tmp; 03282 int x; 03283 int needpush; 03284 ast_mutex_lock(&peerlock); 03285 trans = dr->trans; 03286 while(trans) { 03287 /* Pop off the true root */ 03288 if (trans->eidcount) { 03289 tmp = trans->eids[--trans->eidcount]; 03290 needpush = 1; 03291 } else { 03292 tmp = trans->us_eid; 03293 needpush = 0; 03294 } 03295 03296 peer = peers; 03297 while(peer) { 03298 if (has_permission(peer->include, dr->dcontext) && 03299 dundi_eid_cmp(&peer->eid, &trans->them_eid) && 03300 (peer->order <= order)) { 03301 /* For each other transaction, make sure we don't 03302 ask this EID about the others if they're not 03303 already in the list */ 03304 if (!dundi_eid_cmp(&tmp, &peer->eid)) 03305 x = -1; 03306 else { 03307 for (x=0;x<trans->eidcount;x++) { 03308 if (!dundi_eid_cmp(&trans->eids[x], &peer->eid)) 03309 break; 03310 } 03311 } 03312 if (x == trans->eidcount) { 03313 /* Nope not in the list, if needed, add us at the end since we're the source */ 03314 if (trans->eidcount < DUNDI_MAX_STACK - needpush) { 03315 trans->eids[trans->eidcount++] = peer->eid; 03316 /* Need to insert the real root (or us) at the bottom now as 03317 a requirement now. */ 03318 needpush = 1; 03319 } 03320 } 03321 } 03322 peer = peer->next; 03323 } 03324 /* If necessary, push the true root back on the end */ 03325 if (needpush) 03326 trans->eids[trans->eidcount++] = tmp; 03327 trans = trans->next; 03328 } 03329 ast_mutex_unlock(&peerlock); 03330 return 0; 03331 }
static void populate_addr | ( | struct dundi_peer * | peer, | |
dundi_eid * | eid | |||
) | [static] |
Definition at line 4257 of file pbx_dundi.c.
References dundi_peer::addr, ast_db_get(), ast_sched_add(), do_register_expire(), dundi_eid_to_str(), dundi_peer::eid, and dundi_peer::registerexpire.
Referenced by build_peer().
04258 { 04259 char data[256]; 04260 char *c; 04261 int port, expire; 04262 char eid_str[20]; 04263 dundi_eid_to_str(eid_str, sizeof(eid_str), eid); 04264 if (!ast_db_get("dundi/dpeers", eid_str, data, sizeof(data))) { 04265 c = strchr(data, ':'); 04266 if (c) { 04267 *c = '\0'; 04268 c++; 04269 if (sscanf(c, "%d:%d", &port, &expire) == 2) { 04270 /* Got it! */ 04271 inet_aton(data, &peer->addr.sin_addr); 04272 peer->addr.sin_family = AF_INET; 04273 peer->addr.sin_port = htons(port); 04274 peer->registerexpire = ast_sched_add(sched, (expire + 10) * 1000, do_register_expire, peer); 04275 } 04276 } 04277 } 04278 }
static int precache_trans | ( | struct dundi_transaction * | trans, | |
struct dundi_mapping * | maps, | |||
int | mapcount, | |||
int * | minexp, | |||
int * | foundanswers | |||
) | [static] |
Definition at line 3124 of file pbx_dundi.c.
References ast_log(), ast_sched_add(), dundi_transaction::autokillid, dundi_transaction::autokilltimeout, dundi_request::dcontext, destroy_trans(), do_autokill(), dr, dundi_cache_time, DUNDI_COMMAND_PRECACHERQ, DUNDI_DEFAULT_VERSION, dundi_eid_zero(), DUNDI_IE_ANSWER, dundi_ie_append_answer(), dundi_ie_append_eid(), dundi_ie_append_hint(), dundi_ie_append_short(), dundi_ie_append_str(), DUNDI_IE_CALLED_CONTEXT, DUNDI_IE_CALLED_NUMBER, DUNDI_IE_EID, DUNDI_IE_EXPIRATION, DUNDI_IE_HINT, DUNDI_IE_TTL, DUNDI_IE_VERSION, dundi_lookup_internal(), dundi_lookup_local(), dundi_send(), dundi_transaction::eidcount, dundi_transaction::eids, dundi_hint_metadata::flags, LOG_WARNING, MAX_RESULTS, dundi_request::number, dundi_transaction::parent, dundi_transaction::them_eid, dundi_transaction::ttl, and dundi_transaction::us_eid.
Referenced by precache_transactions().
03125 { 03126 struct dundi_ie_data ied; 03127 int x, res; 03128 int max = 999999; 03129 int expiration = dundi_cache_time; 03130 int ouranswers=0; 03131 dundi_eid *avoid[1] = { NULL, }; 03132 int direct[1] = { 0, }; 03133 struct dundi_result dr[MAX_RESULTS]; 03134 struct dundi_hint_metadata hmd; 03135 if (!trans->parent) { 03136 ast_log(LOG_WARNING, "Tried to discover a transaction with no parent?!?\n"); 03137 return -1; 03138 } 03139 memset(&hmd, 0, sizeof(hmd)); 03140 memset(&dr, 0, sizeof(dr)); 03141 /* Look up the answers we're going to include */ 03142 for (x=0;x<mapcount;x++) 03143 ouranswers = dundi_lookup_local(dr, maps + x, trans->parent->number, &trans->us_eid, ouranswers, &hmd); 03144 if (ouranswers < 0) 03145 ouranswers = 0; 03146 for (x=0;x<ouranswers;x++) { 03147 if (dr[x].weight < max) 03148 max = dr[x].weight; 03149 } 03150 if (max) { 03151 /* If we do not have a canonical result, keep looking */ 03152 res = dundi_lookup_internal(dr + ouranswers, MAX_RESULTS - ouranswers, NULL, trans->parent->dcontext, trans->parent->number, trans->ttl, 1, &hmd, &expiration, 0, 1, &trans->them_eid, avoid, direct); 03153 if (res > 0) { 03154 /* Append answer in result */ 03155 ouranswers += res; 03156 } 03157 } 03158 03159 if (ouranswers > 0) { 03160 *foundanswers += ouranswers; 03161 memset(&ied, 0, sizeof(ied)); 03162 dundi_ie_append_short(&ied, DUNDI_IE_VERSION, DUNDI_DEFAULT_VERSION); 03163 if (!dundi_eid_zero(&trans->us_eid)) 03164 dundi_ie_append_eid(&ied, DUNDI_IE_EID, &trans->us_eid); 03165 for (x=0;x<trans->eidcount;x++) 03166 dundi_ie_append_eid(&ied, DUNDI_IE_EID, &trans->eids[x]); 03167 dundi_ie_append_str(&ied, DUNDI_IE_CALLED_NUMBER, trans->parent->number); 03168 dundi_ie_append_str(&ied, DUNDI_IE_CALLED_CONTEXT, trans->parent->dcontext); 03169 dundi_ie_append_short(&ied, DUNDI_IE_TTL, trans->ttl); 03170 for (x=0;x<ouranswers;x++) { 03171 /* Add answers */ 03172 if (dr[x].expiration && (expiration > dr[x].expiration)) 03173 expiration = dr[x].expiration; 03174 dundi_ie_append_answer(&ied, DUNDI_IE_ANSWER, &dr[x].eid, dr[x].techint, dr[x].flags, dr[x].weight, dr[x].dest); 03175 } 03176 dundi_ie_append_hint(&ied, DUNDI_IE_HINT, hmd.flags, hmd.exten); 03177 dundi_ie_append_short(&ied, DUNDI_IE_EXPIRATION, expiration); 03178 if (trans->autokilltimeout) 03179 trans->autokillid = ast_sched_add(sched, trans->autokilltimeout, do_autokill, trans); 03180 if (expiration < *minexp) 03181 *minexp = expiration; 03182 return dundi_send(trans, DUNDI_COMMAND_PRECACHERQ, 0, 0, &ied); 03183 } else { 03184 /* Oops, nothing to send... */ 03185 destroy_trans(trans, 0); 03186 return 0; 03187 } 03188 }
static int precache_transactions | ( | struct dundi_request * | dr, | |
struct dundi_mapping * | maps, | |||
int | mapcount, | |||
int * | expiration, | |||
int * | foundanswers | |||
) | [static] |
Definition at line 3225 of file pbx_dundi.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, destroy_trans(), dr, FLAG_DEAD, LOG_DEBUG, LOG_WARNING, dundi_transaction::next, precache_trans(), and dundi_transaction::thread.
Referenced by dundi_precache_internal().
03226 { 03227 struct dundi_transaction *trans, *transn; 03228 /* Mark all as "in thread" so they don't disappear */ 03229 ast_mutex_lock(&peerlock); 03230 trans = dr->trans; 03231 while(trans) { 03232 if (trans->thread) 03233 ast_log(LOG_WARNING, "This shouldn't happen, really...\n"); 03234 trans->thread = 1; 03235 trans = trans->next; 03236 } 03237 ast_mutex_unlock(&peerlock); 03238 03239 trans = dr->trans; 03240 while(trans) { 03241 if (!ast_test_flag(trans, FLAG_DEAD)) 03242 precache_trans(trans, maps, mapcount, expiration, foundanswers); 03243 trans = trans->next; 03244 } 03245 03246 /* Cleanup any that got destroyed in the mean time */ 03247 ast_mutex_lock(&peerlock); 03248 trans = dr->trans; 03249 while(trans) { 03250 transn = trans->next; 03251 trans->thread = 0; 03252 if (ast_test_flag(trans, FLAG_DEAD)) { 03253 ast_log(LOG_DEBUG, "Our transaction went away!\n"); 03254 destroy_trans(trans, 0); 03255 } 03256 trans = transn; 03257 } 03258 ast_mutex_unlock(&peerlock); 03259 return 0; 03260 }
static void* process_precache | ( | void * | ign | ) | [static] |
Definition at line 2117 of file pbx_dundi.c.
References ast_mutex_lock(), ast_mutex_unlock(), dundi_precache_queue::context, context, dundi_precache(), dundi_precache_queue::expiration, free, dundi_precache_queue::next, dundi_precache_queue::number, and pcq.
Referenced by start_network_thread().
02118 { 02119 struct dundi_precache_queue *qe; 02120 time_t now; 02121 char context[256]; 02122 char number[256]; 02123 int run; 02124 for (;;) { 02125 time(&now); 02126 run = 0; 02127 ast_mutex_lock(&pclock); 02128 if (pcq) { 02129 if (!pcq->expiration) { 02130 /* Gone... Remove... */ 02131 qe = pcq; 02132 pcq = pcq->next; 02133 free(qe); 02134 } else if (pcq->expiration < now) { 02135 /* Process this entry */ 02136 pcq->expiration = 0; 02137 ast_copy_string(context, pcq->context, sizeof(context)); 02138 ast_copy_string(number, pcq->number, sizeof(number)); 02139 run = 1; 02140 } 02141 } 02142 ast_mutex_unlock(&pclock); 02143 if (run) { 02144 dundi_precache(context, number); 02145 } else 02146 sleep(1); 02147 } 02148 return NULL; 02149 }
static void prune_mappings | ( | void | ) | [static] |
Definition at line 4075 of file pbx_dundi.c.
References ast_mutex_lock(), ast_mutex_unlock(), destroy_map(), map, mappings, and dundi_mapping::next.
Referenced by set_config().
04076 { 04077 struct dundi_mapping *map, *prev, *next; 04078 ast_mutex_lock(&peerlock); 04079 map = mappings; 04080 prev = NULL; 04081 while(map) { 04082 next = map->next; 04083 if (map->dead) { 04084 if (prev) 04085 prev->next = map->next; 04086 else 04087 mappings = map->next; 04088 destroy_map(map); 04089 } else 04090 prev = map; 04091 map = next; 04092 } 04093 ast_mutex_unlock(&peerlock); 04094 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 4054 of file pbx_dundi.c.
References ast_mutex_lock(), ast_mutex_unlock(), dundi_peer::dead, destroy_peer(), dundi_peer::next, and peers.
04055 { 04056 struct dundi_peer *peer, *prev, *next; 04057 ast_mutex_lock(&peerlock); 04058 peer = peers; 04059 prev = NULL; 04060 while(peer) { 04061 next = peer->next; 04062 if (peer->dead) { 04063 if (prev) 04064 prev->next = peer->next; 04065 else 04066 peers = peer->next; 04067 destroy_peer(peer); 04068 } else 04069 prev = peer; 04070 peer = next; 04071 } 04072 ast_mutex_unlock(&peerlock); 04073 }
static void qualify_peer | ( | struct dundi_peer * | peer, | |
int | schedonly | |||
) | [static] |
Definition at line 4232 of file pbx_dundi.c.
References ast_sched_add(), ast_sched_del(), ast_set_flag, create_transaction(), destroy_trans(), do_qualify(), DUNDI_COMMAND_NULL, dundi_send(), FLAG_ISQUAL, dundi_peer::lastms, dundi_peer::maxms, dundi_peer::qualifyid, dundi_peer::qualtrans, and dundi_peer::qualtx.
Referenced by build_peer(), do_qualify(), and handle_command_response().
04233 { 04234 int when; 04235 if (peer->qualifyid > -1) 04236 ast_sched_del(sched, peer->qualifyid); 04237 peer->qualifyid = -1; 04238 if (peer->qualtrans) 04239 destroy_trans(peer->qualtrans, 0); 04240 peer->qualtrans = NULL; 04241 if (peer->maxms > 0) { 04242 when = 60000; 04243 if (peer->lastms < 0) 04244 when = 10000; 04245 if (schedonly) 04246 when = 5000; 04247 peer->qualifyid = ast_sched_add(sched, when, do_qualify, peer); 04248 if (!schedonly) 04249 peer->qualtrans = create_transaction(peer); 04250 if (peer->qualtrans) { 04251 peer->qualtx = ast_tvnow(); 04252 ast_set_flag(peer->qualtrans, FLAG_ISQUAL); 04253 dundi_send(peer->qualtrans, DUNDI_COMMAND_NULL, 0, 1, NULL); 04254 } 04255 } 04256 }
static int query_transactions | ( | struct dundi_request * | dr | ) | [static] |
Definition at line 3262 of file pbx_dundi.c.
References ast_mutex_lock(), ast_mutex_unlock(), dr, and dundi_query().
Referenced by dundi_query_eid_internal().
03263 { 03264 struct dundi_transaction *trans; 03265 ast_mutex_lock(&peerlock); 03266 trans = dr->trans; 03267 while(trans) { 03268 dundi_query(trans); 03269 trans = trans->next; 03270 } 03271 ast_mutex_unlock(&peerlock); 03272 return 0; 03273 }
static int register_request | ( | struct dundi_request * | dr, | |
struct dundi_request ** | pending | |||
) | [static] |
Definition at line 3447 of file pbx_dundi.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), dundi_request::crc32, dundi_request::dcontext, dr, dundi_eid_cmp(), dundi_eid_to_str(), LOG_DEBUG, dundi_request::next, dundi_request::number, option_debug, requests, and dundi_request::root_eid.
Referenced by dundi_lookup_internal().
03448 { 03449 struct dundi_request *cur; 03450 int res=0; 03451 char eid_str[20]; 03452 ast_mutex_lock(&peerlock); 03453 cur = requests; 03454 while(cur) { 03455 if (option_debug) 03456 ast_log(LOG_DEBUG, "Checking '%s@%s' vs '%s@%s'\n", cur->dcontext, cur->number, 03457 dr->dcontext, dr->number); 03458 if (!strcasecmp(cur->dcontext, dr->dcontext) && 03459 !strcasecmp(cur->number, dr->number) && 03460 (!dundi_eid_cmp(&cur->root_eid, &dr->root_eid) || (cur->crc32 == dr->crc32))) { 03461 ast_log(LOG_DEBUG, "Found existing query for '%s@%s' for '%s' crc '%08lx'\n", 03462 cur->dcontext, cur->number, dundi_eid_to_str(eid_str, sizeof(eid_str), &cur->root_eid), cur->crc32); 03463 *pending = cur; 03464 res = 1; 03465 break; 03466 } 03467 cur = cur->next; 03468 } 03469 if (!res) { 03470 ast_log(LOG_DEBUG, "Registering request for '%s@%s' on behalf of '%s' crc '%08lx'\n", 03471 dr->number, dr->dcontext, dundi_eid_to_str(eid_str, sizeof(eid_str), &dr->root_eid), dr->crc32); 03472 /* Go ahead and link us in since nobody else is searching for this */ 03473 dr->next = requests; 03474 requests = dr; 03475 *pending = NULL; 03476 } 03477 ast_mutex_unlock(&peerlock); 03478 return res; 03479 }
int reload | ( | void | ) |
Reload stuff.
This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.
Definition at line 4733 of file pbx_dundi.c.
References set_config().
04734 { 04735 struct sockaddr_in sin; 04736 set_config("dundi.conf",&sin); 04737 return 0; 04738 }
static void reschedule_precache | ( | const char * | number, | |
const char * | context, | |||
int | expiration | |||
) | [static] |
Definition at line 3646 of file pbx_dundi.c.
References ast_mutex_lock(), ast_mutex_unlock(), dundi_precache_queue::context, dundi_precache_queue::expiration, malloc, dundi_precache_queue::next, dundi_precache_queue::number, and pcq.
Referenced by dundi_precache_full(), and dundi_precache_internal().
03647 { 03648 int len; 03649 struct dundi_precache_queue *qe, *prev=NULL; 03650 ast_mutex_lock(&pclock); 03651 qe = pcq; 03652 while(qe) { 03653 if (!strcmp(number, qe->number) && !strcasecmp(context, qe->context)) { 03654 if (prev) 03655 prev->next = qe->next; 03656 else 03657 pcq = qe->next; 03658 qe->next = NULL; 03659 break; 03660 } 03661 prev = qe; 03662 qe = qe->next; 03663 }; 03664 if (!qe) { 03665 len = sizeof(struct dundi_precache_queue); 03666 len += strlen(number) + 1; 03667 len += strlen(context) + 1; 03668 qe = malloc(len); 03669 if (qe) { 03670 memset(qe, 0, len); 03671 strcpy(qe->number, number); 03672 qe->context = qe->number + strlen(number) + 1; 03673 strcpy(qe->context, context); 03674 } 03675 } 03676 time(&qe->expiration); 03677 qe->expiration += expiration; 03678 prev = pcq; 03679 if (prev) { 03680 while(prev->next && (prev->next->expiration <= qe->expiration)) 03681 prev = prev->next; 03682 qe->next = prev->next; 03683 prev->next = qe; 03684 } else 03685 pcq = qe; 03686 ast_mutex_unlock(&pclock); 03687 03688 }
static int rescomp | ( | const void * | a, | |
const void * | b | |||
) | [static] |
Definition at line 2273 of file pbx_dundi.c.
References dundi_result::weight.
Referenced by sort_results().
02274 { 02275 const struct dundi_result *resa, *resb; 02276 resa = a; 02277 resb = b; 02278 if (resa->weight < resb->weight) 02279 return -1; 02280 if (resa->weight > resb->weight) 02281 return 1; 02282 return 0; 02283 }
static void reset_global_eid | ( | void | ) | [static] |
Definition at line 407 of file pbx_dundi.c.
References ast_log(), dundi_eid_to_str(), _dundi_eid::eid, global_eid, LOG_DEBUG, and s.
Referenced by set_config().
00408 { 00409 #if defined(SIOCGIFHWADDR) 00410 int x,s; 00411 char eid_str[20]; 00412 struct ifreq ifr; 00413 00414 s = socket(AF_INET, SOCK_STREAM, 0); 00415 if (s > 0) { 00416 x = 0; 00417 for(x=0;x<10;x++) { 00418 memset(&ifr, 0, sizeof(ifr)); 00419 snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "eth%d", x); 00420 if (!ioctl(s, SIOCGIFHWADDR, &ifr)) { 00421 memcpy(&global_eid, ((unsigned char *)&ifr.ifr_hwaddr) + 2, sizeof(global_eid)); 00422 ast_log(LOG_DEBUG, "Seeding global EID '%s' from '%s'\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &global_eid), ifr.ifr_name); 00423 close(s); 00424 return; 00425 } 00426 } 00427 close(s); 00428 } 00429 #else 00430 #if defined(ifa_broadaddr) && !defined(SOLARIS) 00431 char eid_str[20]; 00432 struct ifaddrs *ifap; 00433 00434 if (getifaddrs(&ifap) == 0) { 00435 struct ifaddrs *p; 00436 for (p = ifap; p; p = p->ifa_next) { 00437 if (p->ifa_addr->sa_family == AF_LINK) { 00438 struct sockaddr_dl* sdp = (struct sockaddr_dl*) p->ifa_addr; 00439 memcpy( 00440 &(global_eid.eid), 00441 sdp->sdl_data + sdp->sdl_nlen, 6); 00442 ast_log(LOG_DEBUG, "Seeding global EID '%s' from '%s'\n", dundi_eid_to_str(eid_str, sizeof(eid_str), &global_eid), ifap->ifa_name); 00443 freeifaddrs(ifap); 00444 return; 00445 } 00446 } 00447 freeifaddrs(ifap); 00448 } 00449 #endif 00450 #endif 00451 ast_log(LOG_NOTICE, "No ethernet interface found for seeding global EID You will have to set it manually.\n"); 00452 }
static int reset_transaction | ( | struct dundi_transaction * | trans | ) | [static] |
Definition at line 473 of file pbx_dundi.c.
References dundi_transaction::aseqno, ast_clear_flag, dundi_transaction::dtrans, FLAG_FINAL, get_trans_id(), dundi_transaction::iseqno, dundi_transaction::oiseqno, dundi_transaction::oseqno, and dundi_transaction::strans.
00474 { 00475 int tid; 00476 tid = get_trans_id(); 00477 if (tid < 1) 00478 return -1; 00479 trans->strans = tid; 00480 trans->dtrans = 0; 00481 trans->iseqno = 0; 00482 trans->oiseqno = 0; 00483 trans->oseqno = 0; 00484 trans->aseqno = 0; 00485 ast_clear_flag(trans, FLAG_FINAL); 00486 return 0; 00487 }
static void save_secret | ( | const char * | newkey, | |
const char * | oldkey | |||
) | [static] |
Definition at line 2026 of file pbx_dundi.c.
References ast_db_put(), DUNDI_SECRET_TIME, rotatetime, and secretpath.
Referenced by check_password(), and load_password().
02027 { 02028 char tmp[256]; 02029 if (oldkey) 02030 snprintf(tmp, sizeof(tmp), "%s;%s", oldkey, newkey); 02031 else 02032 snprintf(tmp, sizeof(tmp), "%s", newkey); 02033 rotatetime = time(NULL) + DUNDI_SECRET_TIME; 02034 ast_db_put(secretpath, "secret", tmp); 02035 snprintf(tmp, sizeof(tmp), "%d", (int)rotatetime); 02036 ast_db_put(secretpath, "secretexpiry", tmp); 02037 }
static int set_config | ( | char * | config_file, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 4553 of file pbx_dundi.c.
References ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_true(), ast_variable_browse(), authdebug, build_mapping(), build_peer(), cfg, country, DEFAULT_MAXMS, dept, dundi_cache_time, DUNDI_DEFAULT_CACHE_TIME, DUNDI_DEFAULT_TTL, DUNDI_MODEL_OUTBOUND, dundi_precache_full(), dundi_str_to_eid(), dundi_ttl, email, format, global_autokilltimeout, global_eid, global_storehistory, hp, ipaddr, IPTOS_MINCOST, ast_variable::lineno, load_password(), locality, LOG_ERROR, LOG_NOTICE, LOG_WARNING, mark_mappings(), mark_peers(), ast_variable::name, ast_variable::next, org, phone, prune_mappings(), prune_peers(), reset_global_eid(), secretpath, stateprov, tos, and ast_variable::value.
04554 { 04555 struct ast_config *cfg; 04556 struct ast_variable *v; 04557 char *cat; 04558 int format; 04559 int x; 04560 char hn[MAXHOSTNAMELEN] = ""; 04561 struct ast_hostent he; 04562 struct hostent *hp; 04563 struct sockaddr_in sin2; 04564 static int last_port = 0; 04565 int globalpcmodel = 0; 04566 dundi_eid testeid; 04567 04568 dundi_ttl = DUNDI_DEFAULT_TTL; 04569 dundi_cache_time = DUNDI_DEFAULT_CACHE_TIME; 04570 cfg = ast_config_load(config_file); 04571 04572 04573 if (!cfg) { 04574 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 04575 return -1; 04576 } 04577 ipaddr[0] = '\0'; 04578 if (!gethostname(hn, sizeof(hn)-1)) { 04579 hp = ast_gethostbyname(hn, &he); 04580 if (hp) { 04581 memcpy(&sin2.sin_addr, hp->h_addr, sizeof(sin2.sin_addr)); 04582 ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin2.sin_addr); 04583 } else 04584 ast_log(LOG_WARNING, "Unable to look up host '%s'\n", hn); 04585 } else 04586 ast_log(LOG_WARNING, "Unable to get host name!\n"); 04587 ast_mutex_lock(&peerlock); 04588 reset_global_eid(); 04589 global_storehistory = 0; 04590 ast_copy_string(secretpath, "dundi", sizeof(secretpath)); 04591 v = ast_variable_browse(cfg, "general"); 04592 while(v) { 04593 if (!strcasecmp(v->name, "port")){ 04594 sin->sin_port = ntohs(atoi(v->value)); 04595 if(last_port==0){ 04596 last_port=sin->sin_port; 04597 } else if(sin->sin_port != last_port) 04598 ast_log(LOG_WARNING, "change to port ignored until next asterisk re-start\n"); 04599 } else if (!strcasecmp(v->name, "bindaddr")) { 04600 struct hostent *hp; 04601 struct ast_hostent he; 04602 hp = ast_gethostbyname(v->value, &he); 04603 if (hp) { 04604 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 04605 } else 04606 ast_log(LOG_WARNING, "Invalid host/IP '%s'\n", v->value); 04607 } else if (!strcasecmp(v->name, "authdebug")) { 04608 authdebug = ast_true(v->value); 04609 } else if (!strcasecmp(v->name, "ttl")) { 04610 if ((sscanf(v->value, "%d", &x) == 1) && (x > 0) && (x < DUNDI_DEFAULT_TTL)) { 04611 dundi_ttl = x; 04612 } else { 04613 ast_log(LOG_WARNING, "'%s' is not a valid TTL at line %d, must be number from 1 to %d\n", 04614 v->value, v->lineno, DUNDI_DEFAULT_TTL); 04615 } 04616 } else if (!strcasecmp(v->name, "autokill")) { 04617 if (sscanf(v->value, "%d", &x) == 1) { 04618 if (x >= 0) 04619 global_autokilltimeout = x; 04620 else 04621 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 04622 } else if (ast_true(v->value)) { 04623 global_autokilltimeout = DEFAULT_MAXMS; 04624 } else { 04625 global_autokilltimeout = 0; 04626 } 04627 } else if (!strcasecmp(v->name, "entityid")) { 04628 if (!dundi_str_to_eid(&testeid, v->value)) 04629 global_eid = testeid; 04630 else 04631 ast_log(LOG_WARNING, "Invalid global endpoint identifier '%s' at line %d\n", v->value, v->lineno); 04632 } else if (!strcasecmp(v->name, "tos")) { 04633 if (sscanf(v->value, "%d", &format) == 1) 04634 tos = format & 0xff; 04635 else if (!strcasecmp(v->value, "lowdelay")) 04636 tos = IPTOS_LOWDELAY; 04637 else if (!strcasecmp(v->value, "throughput")) 04638 tos = IPTOS_THROUGHPUT; 04639 else if (!strcasecmp(v->value, "reliability")) 04640 tos = IPTOS_RELIABILITY; 04641 #if !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(SOLARIS) 04642 else if (!strcasecmp(v->value, "mincost")) 04643 tos = IPTOS_MINCOST; 04644 #endif 04645 else if (!strcasecmp(v->value, "none")) 04646 tos = 0; 04647 else 04648 #if !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(SOLARIS) 04649 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 04650 #else 04651 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', or 'none'\n", v->lineno); 04652 #endif 04653 } else if (!strcasecmp(v->name, "department")) { 04654 ast_copy_string(dept, v->value, sizeof(dept)); 04655 } else if (!strcasecmp(v->name, "organization")) { 04656 ast_copy_string(org, v->value, sizeof(org)); 04657 } else if (!strcasecmp(v->name, "locality")) { 04658 ast_copy_string(locality, v->value, sizeof(locality)); 04659 } else if (!strcasecmp(v->name, "stateprov")) { 04660 ast_copy_string(stateprov, v->value, sizeof(stateprov)); 04661 } else if (!strcasecmp(v->name, "country")) { 04662 ast_copy_string(country, v->value, sizeof(country)); 04663 } else if (!strcasecmp(v->name, "email")) { 04664 ast_copy_string(email, v->value, sizeof(email)); 04665 } else if (!strcasecmp(v->name, "phone")) { 04666 ast_copy_string(phone, v->value, sizeof(phone)); 04667 } else if (!strcasecmp(v->name, "storehistory")) { 04668 global_storehistory = ast_true(v->value); 04669 } else if (!strcasecmp(v->name, "cachetime")) { 04670 if ((sscanf(v->value, "%d", &x) == 1)) { 04671 dundi_cache_time = x; 04672 } else { 04673 ast_log(LOG_WARNING, "'%s' is not a valid cache time at line %d. Using default value '%d'.\n", 04674 v->value, v->lineno, DUNDI_DEFAULT_CACHE_TIME); 04675 } 04676 } 04677 v = v->next; 04678 } 04679 ast_mutex_unlock(&peerlock); 04680 mark_mappings(); 04681 v = ast_variable_browse(cfg, "mappings"); 04682 while(v) { 04683 build_mapping(v->name, v->value); 04684 v = v->next; 04685 } 04686 prune_mappings(); 04687 mark_peers(); 04688 cat = ast_category_browse(cfg, NULL); 04689 while(cat) { 04690 if (strcasecmp(cat, "general") && strcasecmp(cat, "mappings")) { 04691 /* Entries */ 04692 if (!dundi_str_to_eid(&testeid, cat)) 04693 build_peer(&testeid, ast_variable_browse(cfg, cat), &globalpcmodel); 04694 else 04695 ast_log(LOG_NOTICE, "Ignoring invalid EID entry '%s'\n", cat); 04696 } 04697 cat = ast_category_browse(cfg, cat); 04698 } 04699 prune_peers(); 04700 ast_config_destroy(cfg); 04701 load_password(); 04702 if (globalpcmodel & DUNDI_MODEL_OUTBOUND) 04703 dundi_precache_full(); 04704 return 0; 04705 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 1983 of file pbx_dundi.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), dundi_showframe(), dundidebug, handle_frame(), LOG_WARNING, MAX_PACKET_SIZE, and netsocket.
01984 { 01985 struct sockaddr_in sin; 01986 int res; 01987 struct dundi_hdr *h; 01988 char buf[MAX_PACKET_SIZE]; 01989 socklen_t len; 01990 len = sizeof(sin); 01991 res = recvfrom(netsocket, buf, sizeof(buf) - 1, 0,(struct sockaddr *) &sin, &len); 01992 if (res < 0) { 01993 if (errno != ECONNREFUSED) 01994 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 01995 return 1; 01996 } 01997 if (res < sizeof(struct dundi_hdr)) { 01998 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int)sizeof(struct dundi_hdr)); 01999 return 1; 02000 } 02001 buf[res] = '\0'; 02002 h = (struct dundi_hdr *)buf; 02003 if (dundidebug) 02004 dundi_showframe(h, 1, &sin, res - sizeof(struct dundi_hdr)); 02005 ast_mutex_lock(&peerlock); 02006 handle_frame(h, &sin, res - sizeof(struct dundi_hdr)); 02007 ast_mutex_unlock(&peerlock); 02008 return 1; 02009 }
static void sort_results | ( | struct dundi_result * | results, | |
int | count | |||
) | [static] |
Definition at line 2285 of file pbx_dundi.c.
References rescomp().
Referenced by dundi_do_lookup(), dundi_exec(), dundi_lookup_exec(), and dundifunc_read().
02286 { 02287 qsort(results, count, sizeof(results[0]), rescomp); 02288 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 2151 of file pbx_dundi.c.
References ast_pthread_create, netthreadid, network_thread(), precachethreadid, and process_precache().
02152 { 02153 ast_pthread_create(&netthreadid, NULL, network_thread, NULL); 02154 ast_pthread_create(&precachethreadid, NULL, process_precache, NULL); 02155 return 0; 02156 }
static int str2tech | ( | char * | str | ) | [static] |
Definition at line 321 of file pbx_dundi.c.
References DUNDI_PROTO_H323, DUNDI_PROTO_IAX, and DUNDI_PROTO_SIP.
Referenced by build_mapping().
00322 { 00323 if (!strcasecmp(str, "IAX") || !strcasecmp(str, "IAX2")) 00324 return DUNDI_PROTO_IAX; 00325 else if (!strcasecmp(str, "SIP")) 00326 return DUNDI_PROTO_SIP; 00327 else if (!strcasecmp(str, "H323")) 00328 return DUNDI_PROTO_H323; 00329 else 00330 return -1; 00331 }
static char* tech2str | ( | int | tech | ) | [static] |
Definition at line 305 of file pbx_dundi.c.
References DUNDI_PROTO_H323, DUNDI_PROTO_IAX, DUNDI_PROTO_NONE, and DUNDI_PROTO_SIP.
Referenced by cache_lookup_internal(), dundi_lookup_local(), dundi_prop_precache(), dundi_show_mappings(), and handle_command_response().
00306 { 00307 switch(tech) { 00308 case DUNDI_PROTO_NONE: 00309 return "None"; 00310 case DUNDI_PROTO_IAX: 00311 return "IAX2"; 00312 case DUNDI_PROTO_SIP: 00313 return "SIP"; 00314 case DUNDI_PROTO_H323: 00315 return "H323"; 00316 default: 00317 return "Unknown"; 00318 } 00319 }
int unload_module | ( | void | ) |
Cleanup all module structures, sockets, etc.
Standard module functions ...
Definition at line 4707 of file pbx_dundi.c.
References app, ast_cli_unregister(), ast_custom_function_unregister(), ast_unregister_application(), ast_unregister_switch(), cli_debug, cli_flush, cli_lookup, cli_no_debug, cli_no_store_history, cli_precache, cli_queryeid, cli_show_entityid, cli_show_mappings, cli_show_peer, cli_show_peers, cli_show_precache, cli_show_requests, cli_show_trans, cli_store_history, dundi_function, dundi_switch, sched_context_destroy(), and STANDARD_HANGUP_LOCALUSERS.
04708 { 04709 int res; 04710 STANDARD_HANGUP_LOCALUSERS; 04711 ast_cli_unregister(&cli_debug); 04712 ast_cli_unregister(&cli_store_history); 04713 ast_cli_unregister(&cli_flush); 04714 ast_cli_unregister(&cli_no_debug); 04715 ast_cli_unregister(&cli_no_store_history); 04716 ast_cli_unregister(&cli_show_peers); 04717 ast_cli_unregister(&cli_show_entityid); 04718 ast_cli_unregister(&cli_show_trans); 04719 ast_cli_unregister(&cli_show_requests); 04720 ast_cli_unregister(&cli_show_mappings); 04721 ast_cli_unregister(&cli_show_precache); 04722 ast_cli_unregister(&cli_show_peer); 04723 ast_cli_unregister(&cli_lookup); 04724 ast_cli_unregister(&cli_precache); 04725 ast_cli_unregister(&cli_queryeid); 04726 ast_unregister_switch(&dundi_switch); 04727 ast_custom_function_unregister(&dundi_function); 04728 res = ast_unregister_application(app); 04729 sched_context_destroy(sched); 04730 return res; 04731 }
static void unregister_request | ( | struct dundi_request * | dr | ) | [static] |
Definition at line 3481 of file pbx_dundi.c.
References ast_mutex_lock(), ast_mutex_unlock(), dr, dundi_request::next, and requests.
Referenced by dundi_lookup_internal().
03482 { 03483 struct dundi_request *cur, *prev; 03484 ast_mutex_lock(&peerlock); 03485 prev = NULL; 03486 cur = requests; 03487 while(cur) { 03488 if (cur == dr) { 03489 if (prev) 03490 prev->next = cur->next; 03491 else 03492 requests = cur->next; 03493 break; 03494 } 03495 prev = cur; 03496 cur = cur->next; 03497 } 03498 ast_mutex_unlock(&peerlock); 03499 }
static int update_key | ( | struct dundi_peer * | peer | ) | [static] |
Definition at line 1297 of file pbx_dundi.c.
References aes_decrypt_key128(), aes_encrypt_key128(), ast_encrypt_bin, ast_key_get, AST_KEY_PRIVATE, AST_KEY_PUBLIC, ast_log(), ast_sign_bin, build_iv(), dundi_eid_to_str(), dundi_key_ttl, dundi_peer::eid, dundi_peer::inkey, key(), dundi_peer::keyexpire, LOG_NOTICE, dundi_peer::outkey, dundi_peer::sentfullkey, dundi_peer::txenckey, dundi_peer::us_dcx, dundi_peer::us_ecx, and dundi_peer::us_keycrc32.
Referenced by dundi_encrypt().
01298 { 01299 unsigned char key[16]; 01300 struct ast_key *ekey, *skey; 01301 char eid_str[20]; 01302 int res; 01303 if (!peer->keyexpire || (peer->keyexpire < time(NULL))) { 01304 build_iv(key); 01305 aes_encrypt_key128(key, &peer->us_ecx); 01306 aes_decrypt_key128(key, &peer->us_dcx); 01307 ekey = ast_key_get(peer->inkey, AST_KEY_PUBLIC); 01308 if (!ekey) { 01309 ast_log(LOG_NOTICE, "No such key '%s' for creating RSA encrypted shared key for '%s'!\n", 01310 peer->inkey, dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid)); 01311 return -1; 01312 } 01313 skey = ast_key_get(peer->outkey, AST_KEY_PRIVATE); 01314 if (!skey) { 01315 ast_log(LOG_NOTICE, "No such key '%s' for signing RSA encrypted shared key for '%s'!\n", 01316 peer->outkey, dundi_eid_to_str(eid_str, sizeof(eid_str), &peer->eid)); 01317 return -1; 01318 } 01319 if ((res = ast_encrypt_bin(peer->txenckey, key, sizeof(key), ekey)) != 128) { 01320 ast_log(LOG_NOTICE, "Whoa, got a weird encrypt size (%d != %d)!\n", res, 128); 01321 return -1; 01322 } 01323 if ((res = ast_sign_bin(skey, (char *)peer->txenckey, 128, peer->txenckey + 128))) { 01324 ast_log(LOG_NOTICE, "Failed to sign key (%d)!\n", res); 01325 return -1; 01326 } 01327 peer->us_keycrc32 = crc32(0L, peer->txenckey, 128); 01328 peer->sentfullkey = 0; 01329 /* Looks good */ 01330 time(&peer->keyexpire); 01331 peer->keyexpire += dundi_key_ttl; 01332 } 01333 return 0; 01334 }
int usecount | ( | void | ) |
Provides a usecount.
This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 4819 of file pbx_dundi.c.
References STANDARD_USECOUNT.
04820 { 04821 int res; 04822 /* XXX DUNDi cannot be unloaded XXX */ 04823 return 1; 04824 STANDARD_USECOUNT(res); 04825 return res; 04826 }
struct dundi_transaction * alltrans |
Referenced by create_transaction(), dundi_show_trans(), find_transaction(), and get_trans_id().
char* app = "DUNDiLookup" [static] |
Definition at line 82 of file pbx_dundi.c.
char ast_config_AST_KEY_DIR[] |
Definition at line 221 of file asterisk.c.
Referenced by crypto_load(), init_keys(), and osp_build().
int authdebug = 0 [static] |
Definition at line 129 of file pbx_dundi.c.
struct ast_cli_entry cli_debug [static] |
Initial value:
{ { "dundi", "debug", NULL }, dundi_do_debug, "Enable DUNDi debugging", debug_usage }
Definition at line 2727 of file pbx_dundi.c.
struct ast_cli_entry cli_flush [static] |
Initial value:
{ { "dundi", "flush", NULL }, dundi_flush, "Flush DUNDi cache", flush_usage }
Definition at line 2736 of file pbx_dundi.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_lookup [static] |
Initial value:
{ { "dundi", "lookup", NULL }, dundi_do_lookup, "Lookup a number in DUNDi", lookup_usage }
Definition at line 2763 of file pbx_dundi.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_no_debug [static] |
Initial value:
{ { "dundi", "no", "debug", NULL }, dundi_no_debug, "Disable DUNDi debugging", no_debug_usage }
Definition at line 2739 of file pbx_dundi.c.
struct ast_cli_entry cli_no_store_history [static] |
Initial value:
{ { "dundi", "no", "store", "history", NULL }, dundi_no_store_history, "Disable DUNDi historic records", no_store_history_usage }
Definition at line 2733 of file pbx_dundi.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_precache [static] |
Initial value:
{ { "dundi", "precache", NULL }, dundi_do_precache, "Precache a number in DUNDi", precache_usage }
Definition at line 2766 of file pbx_dundi.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_queryeid [static] |
Initial value:
{ { "dundi", "query", NULL }, dundi_do_query, "Query a DUNDi EID", query_usage }
Definition at line 2769 of file pbx_dundi.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_show_entityid [static] |
Initial value:
{ { "dundi", "show", "entityid", NULL }, dundi_show_entityid, "Display Global Entity ID", show_entityid_usage }
Definition at line 2748 of file pbx_dundi.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_show_mappings [static] |
Initial value:
{ { "dundi", "show", "mappings", NULL }, dundi_show_mappings, "Show DUNDi mappings", show_mappings_usage }
Definition at line 2751 of file pbx_dundi.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_show_peer [static] |
Initial value:
{ { "dundi", "show", "peer", NULL }, dundi_show_peer, "Show info on a specific DUNDi peer", show_peer_usage, complete_peer_4 }
Definition at line 2760 of file pbx_dundi.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_show_peers [static] |
Initial value:
{ { "dundi", "show", "peers", NULL }, dundi_show_peers, "Show defined DUNDi peers", show_peers_usage }
Definition at line 2742 of file pbx_dundi.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_show_precache [static] |
Initial value:
{ { "dundi", "show", "precache", NULL }, dundi_show_precache, "Show DUNDi precache", show_precache_usage }
Definition at line 2754 of file pbx_dundi.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_show_requests [static] |
Initial value:
{ { "dundi", "show", "requests", NULL }, dundi_show_requests, "Show DUNDi requests", show_requests_usage }
Definition at line 2757 of file pbx_dundi.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_show_trans [static] |
Initial value:
{ { "dundi", "show", "trans", NULL }, dundi_show_trans, "Show active DUNDi transactions", show_trans_usage }
Definition at line 2745 of file pbx_dundi.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_store_history [static] |
Initial value:
{ { "dundi", "store", "history", NULL }, dundi_do_store_history, "Enable DUNDi historic records", store_history_usage }
Definition at line 2730 of file pbx_dundi.c.
Referenced by load_module(), and unload_module().
char country[80] [static] |
Definition at line 141 of file pbx_dundi.c.
Referenced by dundi_query_thread(), ind_load_module(), and set_config().
char cursecret[80] [static] |
Definition at line 145 of file pbx_dundi.c.
Referenced by check_password(), dundi_lookup_local(), and load_password().
char debug_usage[] [static] |
Initial value:
"Usage: dundi debug\n" " Enables dumping of DUNDi packets for debugging purposes\n"
Definition at line 2657 of file pbx_dundi.c.
int default_expiration = 60 [static] |
Definition at line 135 of file pbx_dundi.c.
Referenced by do_register(), and handle_command_response().
char dept[80] [static] |
char* descrip [static] |
Definition at line 84 of file pbx_dundi.c.
int dundi_cache_time = DUNDI_DEFAULT_CACHE_TIME [static] |
Definition at line 132 of file pbx_dundi.c.
Referenced by cache_save(), cache_save_hint(), dundi_lookup(), dundi_lookup_local(), dundi_lookup_thread(), dundi_precache_internal(), dundi_prop_precache(), handle_command_response(), precache_trans(), and set_config().
int dundi_key_ttl = DUNDI_DEFAULT_KEY_EXPIRE [static] |
struct ast_switch dundi_switch [static] |
int dundi_ttl = DUNDI_DEFAULT_TTL [static] |
Definition at line 130 of file pbx_dundi.c.
Referenced by dundi_lookup(), dundi_precache(), dundi_query_eid(), and set_config().
int dundidebug = 0 [static] |
Definition at line 128 of file pbx_dundi.c.
Referenced by dundi_do_debug(), dundi_no_debug(), dundi_send(), dundi_xmit(), and socket_read().
char email[80] [static] |
char flush_usage[] [static] |
Initial value:
"Usage: dundi flush [stats]\n" " Flushes DUNDi answer cache, used primarily for debug. If\n" "'stats' is present, clears timer statistics instead of normal\n" "operation.\n"
Definition at line 2721 of file pbx_dundi.c.
int global_autokilltimeout = 0 [static] |
dundi_eid global_eid [static] |
Definition at line 134 of file pbx_dundi.c.
Referenced by build_peer(), dundi_show_entityid(), reset_global_eid(), and set_config().
int global_storehistory = 0 [static] |
Definition at line 136 of file pbx_dundi.c.
Referenced by create_transaction(), dundi_do_store_history(), dundi_no_store_history(), and set_config().
struct io_context* io [static] |
Definition at line 122 of file pbx_dundi.c.
char ipaddr[80] [static] |
Definition at line 146 of file pbx_dundi.c.
Referenced by dundi_lookup_local(), realtime_update_peer(), and set_config().
Definition at line 2774 of file pbx_dundi.c.
char locality[80] [static] |
char lookup_usage[] [static] |
Initial value:
"Usage: dundi lookup <number>[@context] [bypass]\n" " Lookup the given number within the given DUNDi context\n" "(or e164 if none is specified). Bypasses cache if 'bypass'\n" "keyword is specified.\n"
Definition at line 2703 of file pbx_dundi.c.
struct dundi_mapping * mappings [static] |
int netsocket = -1 [static] |
Definition at line 124 of file pbx_dundi.c.
Referenced by ast_netsock_bindaddr(), dundi_xmit(), handle_error(), load_module(), network_thread(), and socket_read().
pthread_t netthreadid = AST_PTHREADT_NULL [static] |
Definition at line 125 of file pbx_dundi.c.
char no_debug_usage[] [static] |
Initial value:
"Usage: dundi no debug\n" " Disables dumping of DUNDi packets for debugging purposes\n"
Definition at line 2661 of file pbx_dundi.c.
char no_store_history_usage[] [static] |
Initial value:
"Usage: dundi no store history\n" " Disables storing of DUNDi requests and times for debugging\n" "purposes\n"
Definition at line 2670 of file pbx_dundi.c.
char org[80] [static] |
struct dundi_precache_queue* pcq [static] |
Definition at line 276 of file pbx_dundi.c.
Referenced by dundi_show_precache(), process_precache(), and reschedule_precache().
struct dundi_peer * peers [static] |
char phone[80] [static] |
Definition at line 143 of file pbx_dundi.c.
Referenced by dundi_query_thread(), privacy_exec(), and set_config().
char precache_usage[] [static] |
Initial value:
"Usage: dundi precache <number>[@context]\n" " Lookup the given number within the given DUNDi context\n" "(or e164 if none is specified) and precaches the results to any\n" "upstream DUNDi push servers.\n"
Definition at line 2709 of file pbx_dundi.c.
pthread_t precachethreadid = AST_PTHREADT_NULL [static] |
char query_usage[] [static] |
Initial value:
"Usage: dundi query <entity>[@context]\n" " Attempts to retrieve contact information for a specific\n" "DUNDi entity identifier (EID) within a given DUNDi context (or\n" "e164 if none is specified).\n"
Definition at line 2715 of file pbx_dundi.c.
struct dundi_request * requests |
Referenced by check_request(), dundi_show_requests(), register_request(), and unregister_request().
time_t rotatetime [static] |
Definition at line 147 of file pbx_dundi.c.
Referenced by check_password(), load_password(), and save_secret().
struct sched_context* sched [static] |
Definition at line 123 of file pbx_dundi.c.
char secretpath[80] [static] |
Definition at line 144 of file pbx_dundi.c.
Referenced by load_password(), save_secret(), and set_config().
char show_entityid_usage[] [static] |
Initial value:
"Usage: dundi show entityid\n" " Displays the global entityid for this host.\n"
Definition at line 2691 of file pbx_dundi.c.
char show_mappings_usage[] [static] |
Initial value:
"Usage: dundi show mappings\n" " Lists all known DUNDi mappings.\n"
Definition at line 2683 of file pbx_dundi.c.
char show_peer_usage[] [static] |
Initial value:
"Usage: dundi show peer [peer]\n" " Provide a detailed description of a specifid DUNDi peer.\n"
Definition at line 2695 of file pbx_dundi.c.
char show_peers_usage[] [static] |
Initial value:
"Usage: dundi show peers\n" " Lists all known DUNDi peers.\n"
Definition at line 2675 of file pbx_dundi.c.
char show_precache_usage[] [static] |
Initial value:
"Usage: dundi show precache\n" " Lists all known DUNDi scheduled precache updates.\n"
Definition at line 2687 of file pbx_dundi.c.
char show_requests_usage[] [static] |
Initial value:
"Usage: dundi show requests\n" " Lists all known pending DUNDi requests.\n"
Definition at line 2699 of file pbx_dundi.c.
char show_trans_usage[] [static] |
Initial value:
"Usage: dundi show trans\n" " Lists all known DUNDi transactions.\n"
Definition at line 2679 of file pbx_dundi.c.
Definition at line 2772 of file pbx_dundi.c.
char stateprov[80] [static] |
char store_history_usage[] [static] |
Initial value:
"Usage: dundi store history\n" " Enables storing of DUNDi requests and times for debugging\n" "purposes\n"
Definition at line 2665 of file pbx_dundi.c.
char* synopsis = "Look up a number with DUNDi" [static] |
Definition at line 83 of file pbx_dundi.c.
char* tdesc = "Distributed Universal Number Discovery (DUNDi)" [static] |
Definition at line 80 of file pbx_dundi.c.
int tos = 0 [static] |
Definition at line 127 of file pbx_dundi.c.