[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(&registrations);
+
+	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(&registrations, reg, entry)
 		iax2_do_register(reg);
 	AST_LIST_UNLOCK(&registrations);
+
+	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(&registrations, reg, entry)
 		iax2_do_register(reg);
 	AST_LIST_UNLOCK(&registrations);	
-	
+
+	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