Fix missing locks on mosq->state.

Closes #1374. Thanks to Jeff Trull.
This commit is contained in:
Roger A. Light 2019-09-08 21:11:20 +01:00
parent 31f09d1206
commit ee3591d228
7 changed files with 45 additions and 8 deletions

View File

@ -14,6 +14,7 @@ Broker:
Client library:
- Fix reconnect backoff for the situation where connections are dropped rather
than refused. Closes #737.
- Fix missing locks on `mosq->state`. Closes #1374.
Documentation:
- Improve details on global/per listener options in the mosquitto.conf man page.

View File

@ -53,9 +53,15 @@ int handle__pingreq(struct mosquitto *mosq)
int handle__pingresp(struct mosquitto *mosq)
{
int state;
assert(mosq);
if(mosq->state != mosq_cs_connected){
pthread_mutex_lock(&mosq->state_mutex);
state = mosq->state;
pthread_mutex_unlock(&mosq->state_mutex);
if(state != mosq_cs_connected){
return MOSQ_ERR_PROTOCOL;
}

View File

@ -47,10 +47,15 @@ int handle__pubackcomp(struct mosquitto *mosq, const char *type)
int rc;
mosquitto_property *properties = NULL;
int qos;
int state;
assert(mosq);
if(mosq->state != mosq_cs_connected){
pthread_mutex_lock(&mosq->state_mutex);
state = mosq->state;
pthread_mutex_unlock(&mosq->state_mutex);
if(state != mosq_cs_connected){
return MOSQ_ERR_PROTOCOL;
}

View File

@ -40,10 +40,15 @@ int handle__publish(struct mosquitto *mosq)
uint16_t mid;
int slen;
mosquitto_property *properties = NULL;
int state;
assert(mosq);
if(mosq->state != mosq_cs_connected){
pthread_mutex_lock(&mosq->state_mutex);
state = mosq->state;
pthread_mutex_unlock(&mosq->state_mutex);
if(state != mosq_cs_connected){
return MOSQ_ERR_PROTOCOL;
}

View File

@ -40,10 +40,15 @@ int handle__suback(struct mosquitto *mosq)
int i = 0;
int rc;
mosquitto_property *properties = NULL;
int state;
assert(mosq);
if(mosq->state != mosq_cs_connected){
pthread_mutex_lock(&mosq->state_mutex);
state = mosq->state;
pthread_mutex_unlock(&mosq->state_mutex);
if(state != mosq_cs_connected){
return MOSQ_ERR_PROTOCOL;
}

View File

@ -202,6 +202,7 @@ int packet__write(struct mosquitto *mosq)
{
ssize_t write_length;
struct mosquitto__packet *packet;
int state;
if(!mosq) return MOSQ_ERR_INVAL;
if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
@ -217,10 +218,14 @@ int packet__write(struct mosquitto *mosq)
}
pthread_mutex_unlock(&mosq->out_packet_mutex);
pthread_mutex_lock(&mosq->state_mutex);
state = mosq->state;
pthread_mutex_unlock(&mosq->state_mutex);
#if defined(WITH_TLS) && !defined(WITH_BROKER)
if((mosq->state == mosq_cs_connect_pending) || mosq->want_connect){
if((state == mosq_cs_connect_pending) || mosq->want_connect){
#else
if(mosq->state == mosq_cs_connect_pending){
if(state == mosq_cs_connect_pending){
#endif
pthread_mutex_unlock(&mosq->current_out_packet_mutex);
return MOSQ_ERR_SUCCESS;
@ -316,6 +321,7 @@ int packet__read(struct mosquitto *mosq)
uint8_t byte;
ssize_t read_length;
int rc = 0;
int state;
if(!mosq){
return MOSQ_ERR_INVAL;
@ -323,7 +329,11 @@ int packet__read(struct mosquitto *mosq)
if(mosq->sock == INVALID_SOCKET){
return MOSQ_ERR_NO_CONN;
}
if(mosq->state == mosq_cs_connect_pending){
pthread_mutex_lock(&mosq->state_mutex);
state = mosq->state;
pthread_mutex_unlock(&mosq->state_mutex);
if(state == mosq_cs_connect_pending){
return MOSQ_ERR_SUCCESS;
}

View File

@ -68,6 +68,7 @@ int mosquitto__check_keepalive(struct mosquitto *mosq)
#ifndef WITH_BROKER
int rc;
#endif
int state;
assert(mosq);
#if defined(WITH_BROKER) && defined(WITH_BRIDGE)
@ -88,7 +89,11 @@ int mosquitto__check_keepalive(struct mosquitto *mosq)
if(mosq->keepalive && mosq->sock != INVALID_SOCKET &&
(now >= next_msg_out || now - last_msg_in >= mosq->keepalive)){
if(mosq->state == mosq_cs_connected && mosq->ping_t == 0){
pthread_mutex_lock(&mosq->state_mutex);
state = mosq->state;
pthread_mutex_unlock(&mosq->state_mutex);
if(state == mosq_cs_connected && mosq->ping_t == 0){
send__pingreq(mosq);
/* Reset last msg times to give the server time to send a pingresp */
pthread_mutex_lock(&mosq->msgtime_mutex);