mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
Merge changes from topic 'ASTERISK-24712' into 13
* changes: res_xmpp: Use incremental backoff when a read error occurs res_xmpp: Try to provide useful errors messages from OpenSSL res_xmpp: Correctly check return value of SSL_connect
This commit is contained in:
@@ -2623,12 +2623,31 @@ static int xmpp_client_request_tls(struct ast_xmpp_client *client, struct ast_xm
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
static char *openssl_error_string(void)
|
||||
{
|
||||
char *buf = NULL, *ret;
|
||||
size_t len;
|
||||
BIO *bio = BIO_new(BIO_s_mem());
|
||||
|
||||
ERR_print_errors(bio);
|
||||
len = BIO_get_mem_data(bio, &buf);
|
||||
ret = ast_calloc(1, len + 1);
|
||||
if (ret) {
|
||||
memcpy(ret, buf, len);
|
||||
}
|
||||
BIO_free(bio);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! \brief Internal function called when we receive a response to our TLS initiation request */
|
||||
static int xmpp_client_requested_tls(struct ast_xmpp_client *client, struct ast_xmpp_client_config *cfg, int type, iks *node)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL
|
||||
int sock;
|
||||
long ssl_opts;
|
||||
char *err;
|
||||
#endif
|
||||
|
||||
if (!strcmp(iks_name(node), "success")) {
|
||||
@@ -2664,7 +2683,7 @@ static int xmpp_client_requested_tls(struct ast_xmpp_client *client, struct ast_
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (!SSL_connect(client->ssl_session)) {
|
||||
if (SSL_connect(client->ssl_session) <= 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
@@ -2684,7 +2703,10 @@ static int xmpp_client_requested_tls(struct ast_xmpp_client *client, struct ast_
|
||||
return 0;
|
||||
|
||||
failure:
|
||||
ast_log(LOG_ERROR, "TLS connection for client '%s' cannot be established. OpenSSL initialization failed.\n", client->name);
|
||||
err = openssl_error_string();
|
||||
ast_log(LOG_ERROR, "TLS connection for client '%s' cannot be established. "
|
||||
"OpenSSL initialization failed: %s\n", client->name, err);
|
||||
ast_free(err);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
@@ -3559,6 +3581,7 @@ int ast_xmpp_client_disconnect(struct ast_xmpp_client *client)
|
||||
{
|
||||
if ((client->thread != AST_PTHREADT_NULL) && !pthread_equal(pthread_self(), client->thread)) {
|
||||
xmpp_client_change_state(client, XMPP_STATE_DISCONNECTING);
|
||||
pthread_cancel(client->thread);
|
||||
pthread_join(client->thread, NULL);
|
||||
client->thread = AST_PTHREADT_NULL;
|
||||
}
|
||||
@@ -3738,11 +3761,26 @@ static int xmpp_client_receive(struct ast_xmpp_client *client, unsigned int time
|
||||
return IKS_OK;
|
||||
}
|
||||
|
||||
static void sleep_with_backoff(unsigned int *sleep_time)
|
||||
{
|
||||
/* We're OK with our thread dying here */
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||
|
||||
sleep(*sleep_time);
|
||||
*sleep_time = MIN(60, *sleep_time * 2);
|
||||
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
||||
}
|
||||
|
||||
/*! \brief XMPP client connection thread */
|
||||
static void *xmpp_client_thread(void *data)
|
||||
{
|
||||
struct ast_xmpp_client *client = data;
|
||||
int res = IKS_NET_RWERR;
|
||||
unsigned int sleep_time = 1;
|
||||
|
||||
/* We only allow cancellation while sleeping */
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
||||
|
||||
do {
|
||||
if (client->state == XMPP_STATE_DISCONNECTING) {
|
||||
@@ -3753,7 +3791,7 @@ static void *xmpp_client_thread(void *data)
|
||||
if (res == IKS_NET_RWERR || client->timeout == 0) {
|
||||
ast_debug(3, "[%s] Connecting\n", client->name);
|
||||
if ((res = xmpp_client_reconnect(client)) != IKS_OK) {
|
||||
sleep(4);
|
||||
sleep_with_backoff(&sleep_time);
|
||||
res = IKS_NET_RWERR;
|
||||
}
|
||||
continue;
|
||||
@@ -3792,6 +3830,8 @@ static void *xmpp_client_thread(void *data)
|
||||
}
|
||||
} else if (res == IKS_NET_RWERR) {
|
||||
ast_log(LOG_WARNING, "[%s] Socket read error\n", client->name);
|
||||
ast_xmpp_client_disconnect(client);
|
||||
sleep_with_backoff(&sleep_time);
|
||||
} else if (res == IKS_NET_NOSOCK) {
|
||||
ast_log(LOG_WARNING, "[%s] No socket\n", client->name);
|
||||
} else if (res == IKS_NET_NOCONN) {
|
||||
@@ -3804,6 +3844,8 @@ static void *xmpp_client_thread(void *data)
|
||||
ast_log(LOG_WARNING, "[%s] Dropped?\n", client->name);
|
||||
} else if (res == IKS_NET_UNKNOWN) {
|
||||
ast_debug(5, "[%s] Unknown\n", client->name);
|
||||
} else if (res == IKS_OK) {
|
||||
sleep_time = 1;
|
||||
}
|
||||
|
||||
} while (1);
|
||||
|
Reference in New Issue
Block a user