提交 35e360f1 authored 作者: Chris Rienzo's avatar Chris Rienzo

FS-8619 [mod_rayo] reply with conflict stanza error if bind is attempted with…

FS-8619 [mod_rayo] reply with conflict stanza error if bind is attempted with duplicate JID.  Improve error handling when 'ready' callback fails.
上级 45534616
...@@ -4199,11 +4199,31 @@ static struct rayo_actor *xmpp_stream_client_locate(struct xmpp_stream *stream, ...@@ -4199,11 +4199,31 @@ static struct rayo_actor *xmpp_stream_client_locate(struct xmpp_stream *stream,
return actor; return actor;
} }
/**
* Handle stream resource binding
* @param stream the new stream
*/
static int on_xmpp_stream_bind(struct xmpp_stream *stream)
{
if (!xmpp_stream_is_s2s(stream)) {
/* client belongs to stream */
struct rayo_client *client = rayo_client_create(xmpp_stream_get_jid(stream), xmpp_stream_get_jid(stream), PS_OFFLINE, rayo_client_send, NULL);
if (client) {
xmpp_stream_set_private(stream, client);
} else {
/* this went really bad... */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "failed to create client entity!\n");
return 0;
}
}
return 1;
}
/** /**
* Handle new stream creation * Handle new stream creation
* @param stream the new stream * @param stream the new stream
*/ */
static void on_xmpp_stream_ready(struct xmpp_stream *stream) static int on_xmpp_stream_ready(struct xmpp_stream *stream)
{ {
if (xmpp_stream_is_s2s(stream)) { if (xmpp_stream_is_s2s(stream)) {
if (xmpp_stream_is_incoming(stream)) { if (xmpp_stream_is_incoming(stream)) {
...@@ -4214,6 +4234,7 @@ static void on_xmpp_stream_ready(struct xmpp_stream *stream) ...@@ -4214,6 +4234,7 @@ static void on_xmpp_stream_ready(struct xmpp_stream *stream)
} else { } else {
/* this went really bad... */ /* this went really bad... */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "failed to create peer server entity!\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "failed to create peer server entity!\n");
return 0;
} }
} else { } else {
/* send directed presence to domain */ /* send directed presence to domain */
...@@ -4227,16 +4248,8 @@ static void on_xmpp_stream_ready(struct xmpp_stream *stream) ...@@ -4227,16 +4248,8 @@ static void on_xmpp_stream_ready(struct xmpp_stream *stream)
iks_insert_cdata(x, "chat", 4); iks_insert_cdata(x, "chat", 4);
RAYO_SEND_MESSAGE(globals.server, xmpp_stream_get_jid(stream), presence); RAYO_SEND_MESSAGE(globals.server, xmpp_stream_get_jid(stream), presence);
} }
} else {
/* client belongs to stream */
struct rayo_client *client = rayo_client_create(xmpp_stream_get_jid(stream), xmpp_stream_get_jid(stream), PS_OFFLINE, rayo_client_send, NULL);
if (client) {
xmpp_stream_set_private(stream, client);
} else {
/* this went really bad... */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "failed to create client entity!\n");
}
} }
return 1;
} }
/** /**
...@@ -4486,7 +4499,7 @@ static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_ ...@@ -4486,7 +4499,7 @@ static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing shared secret for %s domain. Server dialback will not work\n", name); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing shared secret for %s domain. Server dialback will not work\n", name);
} }
globals.xmpp_context = xmpp_stream_context_create(name, shared_secret, on_xmpp_stream_ready, on_xmpp_stream_recv, on_xmpp_stream_destroy); globals.xmpp_context = xmpp_stream_context_create(name, shared_secret, on_xmpp_stream_bind, on_xmpp_stream_ready, on_xmpp_stream_recv, on_xmpp_stream_destroy);
globals.server = rayo_server_create(name); globals.server = rayo_server_create(name);
/* set up TLS */ /* set up TLS */
......
/* /*
* mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2013, Grasshopper * Copyright (C) 2013-2015, Grasshopper
* *
* Version: MPL 1.1 * Version: MPL 1.1
* *
...@@ -55,6 +55,8 @@ struct xmpp_stream_context { ...@@ -55,6 +55,8 @@ struct xmpp_stream_context {
switch_hash_t *users; switch_hash_t *users;
/** shared secret for server dialback */ /** shared secret for server dialback */
const char *dialback_secret; const char *dialback_secret;
/** callback when a new resource is bound */
xmpp_stream_bind_callback bind_callback;
/** callback when a new stream is ready */ /** callback when a new stream is ready */
xmpp_stream_ready_callback ready_callback; xmpp_stream_ready_callback ready_callback;
/** callback when a stream is destroyed */ /** callback when a stream is destroyed */
...@@ -539,17 +541,19 @@ static iks *on_iq_set_xmpp_session(struct xmpp_stream *stream, iks *node) ...@@ -539,17 +541,19 @@ static iks *on_iq_set_xmpp_session(struct xmpp_stream *stream, iks *node)
switch(stream->state) { switch(stream->state) {
case XSS_RESOURCE_BOUND: { case XSS_RESOURCE_BOUND: {
reply = iks_new_iq_result(node); if (context->ready_callback && !context->ready_callback(stream)) {
stream->state = XSS_READY; reply = iks_new_error(node, STANZA_ERROR_INTERNAL_SERVER_ERROR);
stream->state = XSS_ERROR;
/* add to available streams */ } else {
switch_mutex_lock(context->streams_mutex); reply = iks_new_iq_result(node);
switch_core_hash_insert(context->routes, stream->jid, stream); stream->state = XSS_READY;
switch_mutex_unlock(context->streams_mutex);
if (context->ready_callback) { /* add to available streams */
context->ready_callback(stream); switch_mutex_lock(context->streams_mutex);
switch_core_hash_insert(context->routes, stream->jid, stream);
switch_mutex_unlock(context->streams_mutex);
} }
break; break;
} }
case XSS_AUTHENTICATED: case XSS_AUTHENTICATED:
...@@ -574,6 +578,7 @@ static iks *on_iq_set_xmpp_bind(struct xmpp_stream *stream, iks *node) ...@@ -574,6 +578,7 @@ static iks *on_iq_set_xmpp_bind(struct xmpp_stream *stream, iks *node)
switch(stream->state) { switch(stream->state) {
case XSS_AUTHENTICATED: { case XSS_AUTHENTICATED: {
struct xmpp_stream_context *context = stream->context;
iks *bind = iks_find(node, "bind"); iks *bind = iks_find(node, "bind");
iks *x; iks *x;
/* get optional client resource ID */ /* get optional client resource ID */
...@@ -585,14 +590,19 @@ static iks *on_iq_set_xmpp_bind(struct xmpp_stream *stream, iks *node) ...@@ -585,14 +590,19 @@ static iks *on_iq_set_xmpp_bind(struct xmpp_stream *stream, iks *node)
switch_uuid_str(resource_id_buf, sizeof(resource_id_buf)); switch_uuid_str(resource_id_buf, sizeof(resource_id_buf));
resource_id = switch_core_strdup(stream->pool, resource_id_buf); resource_id = switch_core_strdup(stream->pool, resource_id_buf);
} }
stream->jid = switch_core_sprintf(stream->pool, "%s/%s", stream->jid, resource_id); stream->jid = switch_core_sprintf(stream->pool, "%s/%s", stream->jid, resource_id);
stream->state = XSS_RESOURCE_BOUND; if (context->bind_callback && !context->bind_callback(stream)) {
stream->jid = NULL;
reply = iks_new_error(node, STANZA_ERROR_CONFLICT);
} else {
stream->state = XSS_RESOURCE_BOUND;
/* create reply */ reply = iks_new_iq_result(node);
reply = iks_new_iq_result(node); x = iks_insert(reply, "bind");
x = iks_insert(reply, "bind"); iks_insert_attrib(x, "xmlns", IKS_NS_XMPP_BIND);
iks_insert_attrib(x, "xmlns", IKS_NS_XMPP_BIND); iks_insert_cdata(iks_insert(x, "jid"), stream->jid, strlen(stream->jid));
iks_insert_cdata(iks_insert(x, "jid"), stream->jid, strlen(stream->jid)); }
break; break;
} }
default: default:
...@@ -732,16 +742,16 @@ static void on_stream_dialback_result_valid(struct xmpp_stream *stream, iks *nod ...@@ -732,16 +742,16 @@ static void on_stream_dialback_result_valid(struct xmpp_stream *stream, iks *nod
/* TODO check domain pair and allow access if pending request exists */ /* TODO check domain pair and allow access if pending request exists */
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_DEBUG, "%s, %s:%i, valid dialback result\n", stream->jid, stream->address, stream->port); switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_DEBUG, "%s, %s:%i, valid dialback result\n", stream->jid, stream->address, stream->port);
/* this stream is routable */ if (context->ready_callback && !context->ready_callback(stream)) {
stream->state = XSS_READY; stream->state = XSS_ERROR;
} else {
/* add to available streams */ /* this stream is routable */
switch_mutex_lock(context->streams_mutex); stream->state = XSS_READY;
switch_core_hash_insert(context->routes, stream->jid, stream);
switch_mutex_unlock(context->streams_mutex);
if (context->ready_callback) { /* add to available streams */
context->ready_callback(stream); switch_mutex_lock(context->streams_mutex);
switch_core_hash_insert(context->routes, stream->jid, stream);
switch_mutex_unlock(context->streams_mutex);
} }
} }
...@@ -816,6 +826,18 @@ static void on_stream_dialback_result_key(struct xmpp_stream *stream, iks *node) ...@@ -816,6 +826,18 @@ static void on_stream_dialback_result_key(struct xmpp_stream *stream, iks *node)
return; return;
} }
/* this stream is not routable */
stream->state = XSS_READY;
stream->jid = switch_core_strdup(stream->pool, from);
if (context->ready_callback && !context->ready_callback(stream)) {
iks *error = iks_new_error(node, STANZA_ERROR_INTERNAL_SERVER_ERROR);
iks_send(stream->parser, error);
iks_delete(error);
stream->state = XSS_ERROR;
return;
}
/* TODO validate key */ /* TODO validate key */
reply = iks_new("db:result"); reply = iks_new("db:result");
iks_insert_attrib(reply, "from", to); iks_insert_attrib(reply, "from", to);
...@@ -823,14 +845,6 @@ static void on_stream_dialback_result_key(struct xmpp_stream *stream, iks *node) ...@@ -823,14 +845,6 @@ static void on_stream_dialback_result_key(struct xmpp_stream *stream, iks *node)
iks_insert_attrib(reply, "type", "valid"); iks_insert_attrib(reply, "type", "valid");
iks_send(stream->parser, reply); iks_send(stream->parser, reply);
iks_delete(reply); iks_delete(reply);
/* this stream is not routable */
stream->state = XSS_READY;
stream->jid = switch_core_strdup(stream->pool, from);
if (context->ready_callback) {
context->ready_callback(stream);
}
} }
/** /**
...@@ -1014,6 +1028,11 @@ static void on_inbound_server_stream_start(struct xmpp_stream *stream, iks *node ...@@ -1014,6 +1028,11 @@ static void on_inbound_server_stream_start(struct xmpp_stream *stream, iks *node
case XSS_SECURE: case XSS_SECURE:
break; break;
case XSS_AUTHENTICATED: { case XSS_AUTHENTICATED: {
if (context->ready_callback && !context->ready_callback(stream)) {
stream->state = XSS_ERROR;
break;
}
/* all set */ /* all set */
xmpp_send_server_header_features(stream); xmpp_send_server_header_features(stream);
stream->state = XSS_READY; stream->state = XSS_READY;
...@@ -1022,10 +1041,6 @@ static void on_inbound_server_stream_start(struct xmpp_stream *stream, iks *node ...@@ -1022,10 +1041,6 @@ static void on_inbound_server_stream_start(struct xmpp_stream *stream, iks *node
switch_mutex_lock(context->streams_mutex); switch_mutex_lock(context->streams_mutex);
switch_core_hash_insert(context->routes, stream->jid, stream); switch_core_hash_insert(context->routes, stream->jid, stream);
switch_mutex_unlock(context->streams_mutex); switch_mutex_unlock(context->streams_mutex);
if (context->ready_callback) {
context->ready_callback(stream);
}
break; break;
} }
case XSS_SHUTDOWN: case XSS_SHUTDOWN:
...@@ -1745,12 +1760,13 @@ void xmpp_stream_context_dump(struct xmpp_stream_context *context, switch_stream ...@@ -1745,12 +1760,13 @@ void xmpp_stream_context_dump(struct xmpp_stream_context *context, switch_stream
* Create a new XMPP stream context * Create a new XMPP stream context
* @param domain for new streams * @param domain for new streams
* @param domain_secret domain shared secret for server dialback * @param domain_secret domain shared secret for server dialback
* @param bind_cb callback function when a resource is bound to a new stream
* @param ready callback function when new stream is ready * @param ready callback function when new stream is ready
* @param recv callback function when a new stanza is received * @param recv callback function when a new stanza is received
* @param destroy callback function when a stream is destroyed * @param destroy callback function when a stream is destroyed
* @return the context * @return the context
*/ */
struct xmpp_stream_context *xmpp_stream_context_create(const char *domain, const char *domain_secret, xmpp_stream_ready_callback ready, xmpp_stream_recv_callback recv, xmpp_stream_destroy_callback destroy) struct xmpp_stream_context *xmpp_stream_context_create(const char *domain, const char *domain_secret, xmpp_stream_bind_callback bind_cb, xmpp_stream_ready_callback ready, xmpp_stream_recv_callback recv, xmpp_stream_destroy_callback destroy)
{ {
switch_memory_pool_t *pool; switch_memory_pool_t *pool;
struct xmpp_stream_context *context; struct xmpp_stream_context *context;
...@@ -1762,6 +1778,7 @@ struct xmpp_stream_context *xmpp_stream_context_create(const char *domain, const ...@@ -1762,6 +1778,7 @@ struct xmpp_stream_context *xmpp_stream_context_create(const char *domain, const
switch_core_hash_init(&context->routes); switch_core_hash_init(&context->routes);
switch_core_hash_init(&context->streams); switch_core_hash_init(&context->streams);
context->dialback_secret = switch_core_strdup(context->pool, domain_secret); context->dialback_secret = switch_core_strdup(context->pool, domain_secret);
context->bind_callback = bind_cb;
context->ready_callback = ready; context->ready_callback = ready;
context->destroy_callback = destroy; context->destroy_callback = destroy;
context->recv_callback = recv; context->recv_callback = recv;
......
/* /*
* mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2013, Grasshopper * Copyright (C) 2013-2015, Grasshopper
* *
* Version: MPL 1.1 * Version: MPL 1.1
* *
...@@ -32,11 +32,12 @@ ...@@ -32,11 +32,12 @@
struct xmpp_stream; struct xmpp_stream;
struct xmpp_stream_context; struct xmpp_stream_context;
typedef void (* xmpp_stream_ready_callback)(struct xmpp_stream *stream); typedef int (* xmpp_stream_bind_callback)(struct xmpp_stream *stream);
typedef int (* xmpp_stream_ready_callback)(struct xmpp_stream *stream);
typedef void (* xmpp_stream_recv_callback)(struct xmpp_stream *stream, iks *stanza); typedef void (* xmpp_stream_recv_callback)(struct xmpp_stream *stream, iks *stanza);
typedef void (* xmpp_stream_destroy_callback)(struct xmpp_stream *stream); typedef void (* xmpp_stream_destroy_callback)(struct xmpp_stream *stream);
extern struct xmpp_stream_context *xmpp_stream_context_create(const char *domain, const char *domain_secret, xmpp_stream_ready_callback ready, xmpp_stream_recv_callback recv, xmpp_stream_destroy_callback destroy); extern struct xmpp_stream_context *xmpp_stream_context_create(const char *domain, const char *domain_secret, xmpp_stream_bind_callback bind_cb, xmpp_stream_ready_callback ready, xmpp_stream_recv_callback recv, xmpp_stream_destroy_callback destroy);
extern void xmpp_stream_context_add_cert(struct xmpp_stream_context *context, const char *cert_pem_file); extern void xmpp_stream_context_add_cert(struct xmpp_stream_context *context, const char *cert_pem_file);
extern void xmpp_stream_context_add_key(struct xmpp_stream_context *context, const char *key_pem_file); extern void xmpp_stream_context_add_key(struct xmpp_stream_context *context, const char *key_pem_file);
extern void xmpp_stream_context_add_user(struct xmpp_stream_context *context, const char *user, const char *password); extern void xmpp_stream_context_add_user(struct xmpp_stream_context *context, const char *user, const char *password);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论