mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-05-31 18:55:49 +00:00
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
3f7d1a5674
commit
ef8d1c7198
@ -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)
|
|||||||
} 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)
|
|||||||
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_
|
|||||||
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 */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* 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 {
|
|||||||
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)
|
|||||||
|
|
||||||
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;
|
||||||
|
} else {
|
||||||
|
reply = iks_new_iq_result(node);
|
||||||
|
stream->state = XSS_READY;
|
||||||
|
|
||||||
/* add to available streams */
|
/* add to available streams */
|
||||||
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_AUTHENTICATED:
|
case XSS_AUTHENTICATED:
|
||||||
@ -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)
|
|||||||
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->state = XSS_RESOURCE_BOUND;
|
|
||||||
|
|
||||||
/* create reply */
|
stream->jid = switch_core_sprintf(stream->pool, "%s/%s", stream->jid, resource_id);
|
||||||
reply = iks_new_iq_result(node);
|
if (context->bind_callback && !context->bind_callback(stream)) {
|
||||||
x = iks_insert(reply, "bind");
|
stream->jid = NULL;
|
||||||
iks_insert_attrib(x, "xmlns", IKS_NS_XMPP_BIND);
|
reply = iks_new_error(node, STANZA_ERROR_CONFLICT);
|
||||||
iks_insert_cdata(iks_insert(x, "jid"), stream->jid, strlen(stream->jid));
|
} 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;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
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 */
|
/* 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 {
|
||||||
|
/* this stream is routable */
|
||||||
|
stream->state = XSS_READY;
|
||||||
|
|
||||||
/* add to available streams */
|
/* add to available streams */
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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)
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
* 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
|
|||||||
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;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* 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 @@
|
|||||||
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user