Handle "error" codes from SSL_connect() correctly.

pull/211/merge
Roger A. Light 11 years ago
parent 45b8220a82
commit 39ffd6fa36

@ -200,6 +200,7 @@ int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_se
mosq->ssl = NULL; mosq->ssl = NULL;
mosq->tls_cert_reqs = SSL_VERIFY_PEER; mosq->tls_cert_reqs = SSL_VERIFY_PEER;
mosq->tls_insecure = false; mosq->tls_insecure = false;
mosq->want_write = false;
#endif #endif
#ifdef WITH_THREADING #ifdef WITH_THREADING
pthread_mutex_init(&mosq->callback_mutex, NULL); pthread_mutex_init(&mosq->callback_mutex, NULL);
@ -839,12 +840,21 @@ int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets)
pthread_mutex_lock(&mosq->out_packet_mutex); pthread_mutex_lock(&mosq->out_packet_mutex);
if(mosq->out_packet || mosq->current_out_packet){ if(mosq->out_packet || mosq->current_out_packet){
FD_SET(mosq->sock, &writefds); FD_SET(mosq->sock, &writefds);
}
#ifdef WITH_TLS #ifdef WITH_TLS
}else if(mosq->ssl && mosq->want_write){ if(mosq->ssl){
FD_SET(mosq->sock, &writefds); if(mosq->want_write){
mosq->want_write = false; FD_SET(mosq->sock, &writefds);
#endif mosq->want_write = false;
}else if(mosq->want_connect){
/* Remove possible FD_SET from above, we don't want to check
* for writing if we are still connecting, unless want_write is
* definitely set. The presence of outgoing packets does not
* matter yet. */
FD_CLR(mosq->sock, &writefds);
}
} }
#endif
pthread_mutex_unlock(&mosq->out_packet_mutex); pthread_mutex_unlock(&mosq->out_packet_mutex);
pthread_mutex_unlock(&mosq->current_out_packet_mutex); pthread_mutex_unlock(&mosq->current_out_packet_mutex);
}else{ }else{
@ -908,9 +918,17 @@ int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets)
}else{ }else{
if(mosq->sock != INVALID_SOCKET){ if(mosq->sock != INVALID_SOCKET){
if(FD_ISSET(mosq->sock, &readfds)){ if(FD_ISSET(mosq->sock, &readfds)){
rc = mosquitto_loop_read(mosq, max_packets); #ifdef WITH_TLS
if(rc || mosq->sock == INVALID_SOCKET){ if(mosq->want_connect){
return rc; rc = mosquitto__socket_connect_tls(mosq);
if(rc) return rc;
}else
#endif
{
rc = mosquitto_loop_read(mosq, max_packets);
if(rc || mosq->sock == INVALID_SOCKET){
return rc;
}
} }
} }
if(mosq->sockpairR >= 0 && FD_ISSET(mosq->sockpairR, &readfds)){ if(mosq->sockpairR >= 0 && FD_ISSET(mosq->sockpairR, &readfds)){
@ -926,9 +944,17 @@ int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets)
FD_SET(mosq->sock, &writefds); FD_SET(mosq->sock, &writefds);
} }
if(FD_ISSET(mosq->sock, &writefds)){ if(FD_ISSET(mosq->sock, &writefds)){
rc = mosquitto_loop_write(mosq, max_packets); #ifdef WITH_TLS
if(rc || mosq->sock == INVALID_SOCKET){ if(mosq->want_connect){
return rc; rc = mosquitto__socket_connect_tls(mosq);
if(rc) return rc;
}else
#endif
{
rc = mosquitto_loop_write(mosq, max_packets);
if(rc || mosq->sock == INVALID_SOCKET){
return rc;
}
} }
} }
} }

@ -180,6 +180,7 @@ struct mosquitto {
bool tls_insecure; bool tls_insecure;
#endif #endif
bool want_write; bool want_write;
bool want_connect;
#if defined(WITH_THREADING) && !defined(WITH_BROKER) #if defined(WITH_THREADING) && !defined(WITH_BROKER)
pthread_mutex_t callback_mutex; pthread_mutex_t callback_mutex;
pthread_mutex_t log_callback_mutex; pthread_mutex_t log_callback_mutex;

@ -372,6 +372,32 @@ int _mosquitto_try_connect(struct mosquitto *mosq, const char *host, uint16_t po
return rc; return rc;
} }
#ifdef WITH_TLS
int mosquitto__socket_connect_tls(struct mosquitto *mosq)
{
int ret;
ret = SSL_connect(mosq->ssl);
if(ret != 1){
ret = SSL_get_error(mosq->ssl, ret);
if(ret == SSL_ERROR_WANT_READ){
mosq->want_connect = true;
/* We always try to read anyway */
}else if(ret == SSL_ERROR_WANT_WRITE){
mosq->want_write = true;
mosq->want_connect = true;
}else{
COMPAT_CLOSE(mosq->sock);
mosq->sock = INVALID_SOCKET;
return MOSQ_ERR_TLS;
}
}else{
mosq->want_connect = false;
}
return MOSQ_ERR_SUCCESS;
}
#endif
/* Create a socket and connect it to 'ip' on port 'port'. /* Create a socket and connect it to 'ip' on port 'port'.
* Returns -1 on failure (ip is NULL, socket creation/connection error) * Returns -1 on failure (ip is NULL, socket creation/connection error)
* Returns sock number on success. * Returns sock number on success.
@ -519,18 +545,11 @@ int _mosquitto_socket_connect(struct mosquitto *mosq, const char *host, uint16_t
} }
SSL_set_bio(mosq->ssl, bio, bio); SSL_set_bio(mosq->ssl, bio, bio);
ret = SSL_connect(mosq->ssl); mosq->sock = sock;
if(ret != 1){ if(mosquitto__socket_connect_tls(mosq)){
ret = SSL_get_error(mosq->ssl, ret); return MOSQ_ERR_TLS;
if(ret == SSL_ERROR_WANT_READ){
/* We always try to read anyway */
}else if(ret == SSL_ERROR_WANT_WRITE){
mosq->want_write = true;
}else{
COMPAT_CLOSE(sock);
return MOSQ_ERR_TLS;
}
} }
} }
#endif #endif

@ -86,6 +86,7 @@ int _mosquitto_packet_read(struct mosquitto *mosq);
#ifdef WITH_TLS #ifdef WITH_TLS
int _mosquitto_socket_apply_tls(struct mosquitto *mosq); int _mosquitto_socket_apply_tls(struct mosquitto *mosq);
int mosquitto__socket_connect_tls(struct mosquitto *mosq);
#endif #endif
#endif #endif

Loading…
Cancel
Save