[asterisk-commits] russell: branch russell/events r73843 - in /team/russell/events: channels/ in...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sat Jul 7 21:19:20 CDT 2007
Author: russell
Date: Sat Jul 7 21:19:19 2007
New Revision: 73843
URL: http://svn.digium.com/view/asterisk?view=rev&rev=73843
Log:
commit some iax2 changes i started to make a long time ago so they are
backed up ... still plenty to do before it does something useful
Modified:
team/russell/events/channels/chan_iax2.c
team/russell/events/channels/iax2.h
team/russell/events/include/asterisk/frame.h
Modified: team/russell/events/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/channels/chan_iax2.c?view=diff&rev=73843&r1=73842&r2=73843
==============================================================================
--- team/russell/events/channels/chan_iax2.c (original)
+++ team/russell/events/channels/chan_iax2.c Sat Jul 7 21:19:19 2007
@@ -296,6 +296,11 @@
static int reload_config(void);
static int iax2_reload(int fd, int argc, char *argv[]);
+enum resource_peer_type {
+ RESOURCE_PEER_INBOUND = (1 << 0),
+ RESOURCE_PEER_OUTBOUND = (1 << 1),
+ RESOURCE_PEER_SYMMETRIC = RESOURCE_PEER_INBOUND | RESOURCE_PEER_OUTBOUND,
+};
struct iax2_user {
AST_DECLARE_STRING_FIELDS(
@@ -323,12 +328,14 @@
struct ast_ha *ha;
struct iax2_context *contexts;
struct ast_variable *vars;
+ enum resource_peer_type resource_peer_type:2;
AST_LIST_ENTRY(iax2_user) entry;
};
struct iax2_peer {
AST_DECLARE_STRING_FIELDS(
AST_STRING_FIELD(name);
+ AST_STRING_FIELD(host);
AST_STRING_FIELD(username);
AST_STRING_FIELD(secret);
AST_STRING_FIELD(dbsecret);
@@ -377,6 +384,9 @@
struct ast_event_sub *mwi_event_sub;
+ enum resource_peer_type resource_peer_type:2;
+ unsigned int rp_init:1;
+
struct ast_ha *ha;
AST_LIST_ENTRY(iax2_peer) entry;
};
@@ -452,6 +462,48 @@
};
static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
+
+enum resource_peer_state {
+ RP_STATE_DISCONNECTED = 0,
+ RP_STATE_RPREQSENT,
+ RP_STATE_AUTHSENT,
+ RP_STATE_CONNECTED,
+ RP_STATE_REJECTED,
+ RP_STATE_TIMEOUT,
+ RP_STATE_NOAUTH,
+};
+
+/*! A resource peering session */
+struct iax2_resource_peer {
+ AST_LIST_ENTRY(iax2_resource_peer) entry;
+
+ AST_DECLARE_STRING_FIELDS (
+ AST_STRING_FIELD(host);
+ AST_STRING_FIELD(username);
+ AST_STRING_FIELD(secret);
+ );
+
+ /*! Initiate the connection to this resource peer */
+ unsigned int init:1;
+ /*! Inbound, Outbound, or both */
+ enum resource_peer_type type:2;
+ /*! Scheduler ID for when to expire this session */
+ int expire_sched_id;
+ /*! The negotiated refresh time */
+ unsigned int refresh;
+ /*! Call number for this session if one exists */
+ unsigned short callno;
+ /*! DNS manager entry for the remote host */
+ struct ast_dnsmgr_entry *dnsmgr;
+ /*! The address of the remote host */
+ struct sockaddr_in addr;
+
+ enum resource_peer_state state;
+
+ struct ast_event_sub *sub;
+};
+
+static AST_LIST_HEAD_STATIC(resource_peers, iax2_resource_peer);
/* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
#define MIN_RETRY_TIME 100
@@ -601,6 +653,8 @@
unsigned char semirand[32];
/*! Associated registry */
struct iax2_registry *reg;
+ /*! Associated resource peering session */
+ struct iax2_resource_peer *rp;
/*! Associated peer for poking */
struct iax2_peer *peerpoke;
/*! IAX_ flags */
@@ -6813,6 +6867,11 @@
.read = acf_iaxvar_read,
.write = acf_iaxvar_write,
};
+
+static void process_rpreq(unsigned short callno, struct sockaddr_in *sin, struct iax_ies *ies)
+{
+
+}
static int socket_process(struct iax2_thread *thread)
{
@@ -7839,6 +7898,9 @@
/* Force retransmission */
vnak_retransmit(fr->callno, fr->iseqno);
break;
+ case IAX_COMMAND_RPREQ:
+ process_rpreq(fr->callno, &sin, &ies);
+ break;
case IAX_COMMAND_REGREQ:
case IAX_COMMAND_REGREL:
/* For security, always ack immediately */
@@ -8799,7 +8861,140 @@
}
}
-
+static enum resource_peer_type resource_peer_get_type(const char *val)
+{
+ if (!strcasecmp(val, "symmetric"))
+ return RESOURCE_PEER_SYMMETRIC;
+ else if (!strcasecmp(val, "inbound"))
+ return RESOURCE_PEER_INBOUND;
+ else if (!strcasecmp(val, "outbound"))
+ return RESOURCE_PEER_OUTBOUND;
+
+ return 0;
+}
+
+static void resource_peer_destroy(struct iax2_resource_peer *rp)
+{
+ if (rp->sub) {
+ ast_event_unsubscribe(rp->sub);
+ rp->sub = NULL;
+ }
+
+ if (rp->dnsmgr) {
+ ast_dnsmgr_release(rp->dnsmgr);
+ rp->dnsmgr = NULL;
+ }
+
+ /* XXX Remove all subscriptions from the other side */
+
+ /* XXX Send RPREL */
+
+ ast_string_field_free_pools(rp);
+ free(rp);
+}
+
+static void resource_peer_append(struct iax2_peer *peer)
+{
+ struct iax2_resource_peer *rp;
+
+ if (!(ast_calloc(1, sizeof(*rp))))
+ return;
+
+ if (ast_string_field_init(rp, 32)) {
+ free(rp);
+ return;
+ }
+
+ ast_string_field_set(rp, username, peer->username);
+ ast_string_field_set(rp, secret, peer->secret);
+ rp->type = peer->resource_peer_type;
+ rp->init = peer->rp_init;
+
+ if (rp->init) {
+ ast_string_field_set(rp, host, peer->host);
+ memcpy(&rp->addr, &peer->addr, sizeof(rp->addr));
+ if (ast_dnsmgr_lookup(rp->host, &rp->addr.sin_addr, &rp->dnsmgr) < 0) {
+ ast_string_field_free_pools(rp);
+ free(rp);
+ return;
+ }
+ }
+
+ rp->expire_sched_id = -1;
+ rp->refresh = IAX_DEFAULT_RP_EXPIRE;
+
+ AST_LIST_LOCK(&resource_peers);
+ AST_LIST_INSERT_TAIL(&resource_peers, rp, entry);
+ AST_LIST_UNLOCK(&resource_peers);
+}
+
+static void resource_peer_init(struct iax2_resource_peer *rp);
+
+static void __resource_peer_init_s(void *data)
+{
+ resource_peer_init(data);
+}
+
+static int resource_peer_init_s(void *data)
+{
+#ifdef SCHED_MULTITHREADED
+ if (schedule_action(__resource_peer_init_s, data))
+#endif
+ resource_peer_init(data);
+
+ return 0;
+}
+
+/*! Initiate the connection to a resource peer */
+static void resource_peer_init(struct iax2_resource_peer *rp)
+{
+ struct iax_ie_data ied;
+
+ if (!rp->init)
+ return;
+
+ if (rp->dnsmgr &&
+ ((rp->state == RP_STATE_TIMEOUT) || !rp->addr.sin_addr.s_addr)) {
+ /* Maybe the IP has changed, force DNS refresh */
+ ast_dnsmgr_refresh(rp->dnsmgr);
+ }
+
+ if (rp->dnsmgr && ast_dnsmgr_changed(rp->dnsmgr) && rp->callno > 0) {
+ ast_mutex_lock(&iaxsl[rp->callno]);
+ iax2_destroy(rp->callno);
+ ast_mutex_unlock(&iaxsl[rp->callno]);
+ rp->callno = 0;
+ }
+
+ if (!rp->addr.sin_addr.s_addr) {
+ if (option_debug) {
+ ast_log(LOG_DEBUG, "Unable to initiate resource peering for '%s' without IP address\n",
+ rp->host);
+ }
+ if (rp->expire_sched_id > -1)
+ ast_sched_del(sched, rp->expire_sched_id);
+ rp->expire_sched_id = ast_sched_add(sched, (5 * rp->refresh / 6) * 1000, resource_peer_init_s, rp);
+ }
+
+ if (!rp->callno) {
+ rp->callno = find_callno(0, 0, &rp->addr, NEW_FORCE, 1, defaultsockfd);
+ if (rp->callno < 1) {
+
+ }
+ iaxs[rp->callno]->rp = rp;
+ }
+
+ if (rp->expire_sched_id > -1)
+ ast_sched_del(sched, rp->expire_sched_id);
+ rp->expire_sched_id = ast_sched_add(sched, (5 * rp->refresh / 6) * 1000, resource_peer_init_s, rp);
+
+ memset(&ied, 0, sizeof(ied));
+ iax_ie_append_str(&ied, IAX_IE_USERNAME, rp->username);
+ iax_ie_append_short(&ied, IAX_IE_REFRESH, rp->refresh);
+ send_command(iaxs[rp->callno], AST_FRAME_IAX, IAX_COMMAND_RPREQ, 0, ied.buf, ied.pos, -1);
+ rp->state = RP_STATE_RPREQSENT;
+}
+
/*! \brief Create peer structure based on configuration */
static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
{
@@ -8919,6 +9114,7 @@
ast_sched_del(sched, peer->expire);
peer->expire = -1;
ast_clear_flag(peer, IAX_DYNAMIC);
+ ast_string_field_set(peer, host, v->value);
if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) {
ast_string_field_free_pools(peer);
ast_free(peer);
@@ -9018,6 +9214,10 @@
} else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
} else if (!strcasecmp(v->name, "timezone")) {
ast_string_field_set(peer, zonetag, v->value);
+ } else if (!strcasecmp(v->name, "resourcepeer")) {
+ peer->resource_peer_type = resource_peer_get_type(v->value);
+ } else if (!strcasecmp(v->name, "rpinitiate")) {
+ peer->rp_init = ast_true(v->value);
} else if (!strcasecmp(v->name, "adsi")) {
peer->adsi = ast_true(v->value);
}/* else if (strcasecmp(v->name,"type")) */
@@ -9043,6 +9243,9 @@
AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, peer->mailbox,
AST_EVENT_IE_END);
}
+
+ if (peer->resource_peer_type)
+ resource_peer_append(peer);
return peer;
}
@@ -9232,6 +9435,8 @@
user->maxauthreq = atoi(v->value);
if (user->maxauthreq < 0)
user->maxauthreq = 0;
+ } else if (!strcasecmp(v->name, "resourcepeer")) {
+ user->resource_peer_type = resource_peer_get_type(v->value);
} else if (!strcasecmp(v->name, "adsi")) {
user->adsi = ast_true(v->value);
}/* else if (strcasecmp(v->name,"type")) */
@@ -9267,6 +9472,7 @@
struct iax2_user *user;
struct iax2_peer *peer;
struct iax2_registry *reg;
+ struct iax2_resource_peer *rp;
AST_LIST_LOCK(&users);
AST_LIST_TRAVERSE(&users, user, entry)
@@ -9290,6 +9496,11 @@
ast_free(reg);
}
AST_LIST_UNLOCK(®istrations);
+
+ AST_LIST_LOCK(&resource_peers);
+ while ((rp = AST_RWLIST_REMOVE_HEAD(&resource_peers, entry)))
+ resource_peer_destroy(rp);
+ AST_LIST_UNLOCK(&resource_peers);
AST_LIST_LOCK(&peers);
AST_LIST_TRAVERSE(&peers, peer, entry)
@@ -9772,6 +9983,7 @@
char *config = "iax.conf";
struct iax2_registry *reg;
struct iax2_peer *peer;
+ struct iax2_resource_peer *rp;
strcpy(accountcode, "");
strcpy(language, "");
@@ -9796,6 +10008,11 @@
AST_LIST_TRAVERSE(®istrations, reg, entry)
iax2_do_register(reg);
AST_LIST_UNLOCK(®istrations);
+
+ AST_LIST_LOCK(&resource_peers);
+ AST_LIST_TRAVERSE(&resource_peers, rp, entry)
+ resource_peer_init(rp);
+ AST_LIST_UNLOCK(&resource_peers);
/* Qualify hosts, too */
AST_LIST_LOCK(&peers);
@@ -10630,7 +10847,8 @@
int x = 0;
struct iax2_registry *reg = NULL;
struct iax2_peer *peer = NULL;
-
+ struct iax2_resource_peer *rp;
+
ast_custom_function_register(&iaxpeer_function);
ast_custom_function_register(&iaxvar_function);
@@ -10713,7 +10931,12 @@
AST_LIST_TRAVERSE(®istrations, reg, entry)
iax2_do_register(reg);
AST_LIST_UNLOCK(®istrations);
-
+
+ AST_LIST_LOCK(&resource_peers);
+ AST_LIST_TRAVERSE(&resource_peers, rp, entry)
+ resource_peer_init(rp);
+ AST_LIST_UNLOCK(&resource_peers);
+
AST_LIST_LOCK(&peers);
AST_LIST_TRAVERSE(&peers, peer, entry) {
if (peer->sockfd < 0)
Modified: team/russell/events/channels/iax2.h
URL: http://svn.digium.com/view/asterisk/team/russell/events/channels/iax2.h?view=diff&rev=73843&r1=73842&r2=73843
==============================================================================
--- team/russell/events/channels/iax2.h (original)
+++ team/russell/events/channels/iax2.h Sat Jul 7 21:19:19 2007
@@ -95,10 +95,23 @@
IAX_COMMAND_FWDATA = 37,
/*! Transfer media only */
IAX_COMMAND_TXMEDIA = 38,
+ /*! Resource Peering request */
+ IAX_COMMAND_RPREQ = 39,
+ /*! Resource Peering authentication required */
+ IAX_COMMAND_RPAUTH = 40,
+ /*! Resource Peering accepted */
+ IAX_COMMAND_RPACK = 41,
+ /*! Resource Peering rejected */
+ IAX_COMMAND_RPREJ = 42,
+ /*! Force release of Resource Peering */
+ IAX_COMMAND_RPREL = 43,
};
/*! By default require re-registration once per minute */
#define IAX_DEFAULT_REG_EXPIRE 60
+
+/*! The default expiry for resource peering sessions */
+#define IAX_DEFAULT_RP_EXPIRE 60
/*! How long to wait before closing bridged call */
#define IAX_LINGER_TIMEOUT 10
Modified: team/russell/events/include/asterisk/frame.h
URL: http://svn.digium.com/view/asterisk/team/russell/events/include/asterisk/frame.h?view=diff&rev=73843&r1=73842&r2=73843
==============================================================================
--- team/russell/events/include/asterisk/frame.h (original)
+++ team/russell/events/include/asterisk/frame.h Sat Jul 7 21:19:19 2007
@@ -121,6 +121,8 @@
AST_FRAME_MODEM,
/*! DTMF begin event, subclass is the digit */
AST_FRAME_DTMF_BEGIN,
+ /*! A reserved frame type ID for generic Asterisk events */
+ AST_FRAME_EVENT,
};
#define AST_FRAME_DTMF AST_FRAME_DTMF_END
More information about the asterisk-commits
mailing list