FS-8619 [mod_rayo] reply with conflict stanza error if bind is attempted with duplicate JID. Improve error handling when 'ready' callback fails.
This commit is contained in:
parent
45534616c6
commit
35e360f1e4
|
@ -4199,11 +4199,31 @@ static struct rayo_actor *xmpp_stream_client_locate(struct xmpp_stream *stream,
|
|||
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
|
||||
* @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_incoming(stream)) {
|
||||
|
@ -4214,6 +4234,7 @@ static void on_xmpp_stream_ready(struct xmpp_stream *stream)
|
|||
} else {
|
||||
/* this went really bad... */
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "failed to create peer server entity!\n");
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/* send directed presence to domain */
|
||||
|
@ -4227,16 +4248,8 @@ static void on_xmpp_stream_ready(struct xmpp_stream *stream)
|
|||
iks_insert_cdata(x, "chat", 4);
|
||||
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_
|
|||
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);
|
||||
|
||||
/* set up TLS */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
|
@ -55,6 +55,8 @@ struct xmpp_stream_context {
|
|||
switch_hash_t *users;
|
||||
/** shared secret for server dialback */
|
||||
const char *dialback_secret;
|
||||
/** callback when a new resource is bound */
|
||||
xmpp_stream_bind_callback bind_callback;
|
||||
/** callback when a new stream is ready */
|
||||
xmpp_stream_ready_callback ready_callback;
|
||||
/** callback when a stream is destroyed */
|
||||
|
@ -539,17 +541,19 @@ static iks *on_iq_set_xmpp_session(struct xmpp_stream *stream, iks *node)
|
|||
|
||||
switch(stream->state) {
|
||||
case XSS_RESOURCE_BOUND: {
|
||||
reply = iks_new_iq_result(node);
|
||||
stream->state = XSS_READY;
|
||||
if (context->ready_callback && !context->ready_callback(stream)) {
|
||||
reply = iks_new_error(node, STANZA_ERROR_INTERNAL_SERVER_ERROR);
|
||||
stream->state = XSS_ERROR;
|
||||
} else {
|
||||
reply = iks_new_iq_result(node);
|
||||
stream->state = XSS_READY;
|
||||
|
||||
/* add to available streams */
|
||||
switch_mutex_lock(context->streams_mutex);
|
||||
switch_core_hash_insert(context->routes, stream->jid, stream);
|
||||
switch_mutex_unlock(context->streams_mutex);
|
||||
|
||||
if (context->ready_callback) {
|
||||
context->ready_callback(stream);
|
||||
/* add to available streams */
|
||||
switch_mutex_lock(context->streams_mutex);
|
||||
switch_core_hash_insert(context->routes, stream->jid, stream);
|
||||
switch_mutex_unlock(context->streams_mutex);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case XSS_AUTHENTICATED:
|
||||
|
@ -574,6 +578,7 @@ static iks *on_iq_set_xmpp_bind(struct xmpp_stream *stream, iks *node)
|
|||
|
||||
switch(stream->state) {
|
||||
case XSS_AUTHENTICATED: {
|
||||
struct xmpp_stream_context *context = stream->context;
|
||||
iks *bind = iks_find(node, "bind");
|
||||
iks *x;
|
||||
/* get optional client resource ID */
|
||||
|
@ -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));
|
||||
resource_id = switch_core_strdup(stream->pool, resource_id_buf);
|
||||
}
|
||||
stream->jid = switch_core_sprintf(stream->pool, "%s/%s", stream->jid, resource_id);
|
||||
stream->state = XSS_RESOURCE_BOUND;
|
||||
|
||||
/* create reply */
|
||||
reply = iks_new_iq_result(node);
|
||||
x = iks_insert(reply, "bind");
|
||||
iks_insert_attrib(x, "xmlns", IKS_NS_XMPP_BIND);
|
||||
iks_insert_cdata(iks_insert(x, "jid"), stream->jid, strlen(stream->jid));
|
||||
stream->jid = switch_core_sprintf(stream->pool, "%s/%s", stream->jid, resource_id);
|
||||
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;
|
||||
|
||||
reply = iks_new_iq_result(node);
|
||||
x = iks_insert(reply, "bind");
|
||||
iks_insert_attrib(x, "xmlns", IKS_NS_XMPP_BIND);
|
||||
iks_insert_cdata(iks_insert(x, "jid"), stream->jid, strlen(stream->jid));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -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 */
|
||||
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 */
|
||||
stream->state = XSS_READY;
|
||||
if (context->ready_callback && !context->ready_callback(stream)) {
|
||||
stream->state = XSS_ERROR;
|
||||
} else {
|
||||
/* this stream is routable */
|
||||
stream->state = XSS_READY;
|
||||
|
||||
/* add to available streams */
|
||||
switch_mutex_lock(context->streams_mutex);
|
||||
switch_core_hash_insert(context->routes, stream->jid, stream);
|
||||
switch_mutex_unlock(context->streams_mutex);
|
||||
|
||||
if (context->ready_callback) {
|
||||
context->ready_callback(stream);
|
||||
/* add to available streams */
|
||||
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)
|
|||
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 */
|
||||
reply = iks_new("db:result");
|
||||
iks_insert_attrib(reply, "from", to);
|
||||
|
@ -823,14 +845,6 @@ static void on_stream_dialback_result_key(struct xmpp_stream *stream, iks *node)
|
|||
iks_insert_attrib(reply, "type", "valid");
|
||||
iks_send(stream->parser, 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
|
|||
case XSS_SECURE:
|
||||
break;
|
||||
case XSS_AUTHENTICATED: {
|
||||
if (context->ready_callback && !context->ready_callback(stream)) {
|
||||
stream->state = XSS_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* all set */
|
||||
xmpp_send_server_header_features(stream);
|
||||
stream->state = XSS_READY;
|
||||
|
@ -1022,10 +1041,6 @@ static void on_inbound_server_stream_start(struct xmpp_stream *stream, iks *node
|
|||
switch_mutex_lock(context->streams_mutex);
|
||||
switch_core_hash_insert(context->routes, stream->jid, stream);
|
||||
switch_mutex_unlock(context->streams_mutex);
|
||||
|
||||
if (context->ready_callback) {
|
||||
context->ready_callback(stream);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XSS_SHUTDOWN:
|
||||
|
@ -1745,12 +1760,13 @@ void xmpp_stream_context_dump(struct xmpp_stream_context *context, switch_stream
|
|||
* Create a new XMPP stream context
|
||||
* @param domain for new streams
|
||||
* @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 recv callback function when a new stanza is received
|
||||
* @param destroy callback function when a stream is destroyed
|
||||
* @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;
|
||||
struct xmpp_stream_context *context;
|
||||
|
@ -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->streams);
|
||||
context->dialback_secret = switch_core_strdup(context->pool, domain_secret);
|
||||
context->bind_callback = bind_cb;
|
||||
context->ready_callback = ready;
|
||||
context->destroy_callback = destroy;
|
||||
context->recv_callback = recv;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
|
@ -32,11 +32,12 @@
|
|||
struct xmpp_stream;
|
||||
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_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_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);
|
||||
|
|
Loading…
Reference in New Issue