From e185d18917d3f6372845e5a04e5ed1520b7c7672 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Wed, 8 Aug 2018 15:23:03 +0100 Subject: [PATCH] Better fix for #851. Ensure all sockets that are closed are set to INVALID_SOCKET. Signed-off-by: Roger A. Light --- lib/net_mosq.c | 50 +++++++++++++++++++++++++++++++------------------- lib/net_mosq.h | 2 +- src/net.c | 4 ++-- 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/lib/net_mosq.c b/lib/net_mosq.c index c6f2561e..946417b5 100644 --- a/lib/net_mosq.c +++ b/lib/net_mosq.c @@ -251,11 +251,12 @@ int net__try_connect_step2(struct mosquitto *mosq, uint16_t port, mosq_sock_t *s ((struct sockaddr_in6 *)rp->ai_addr)->sin6_port = htons(port); }else{ COMPAT_CLOSE(*sock); + *sock = INVALID_SOCKET; continue; } /* Set non-blocking */ - if(net__socket_nonblock(*sock)){ + if(net__socket_nonblock(sock)){ continue; } @@ -269,7 +270,7 @@ int net__try_connect_step2(struct mosquitto *mosq, uint16_t port, mosq_sock_t *s } /* Set non-blocking */ - if(net__socket_nonblock(*sock)){ + if(net__socket_nonblock(sock)){ continue; } break; @@ -335,6 +336,7 @@ int net__try_connect(struct mosquitto *mosq, const char *host, uint16_t port, mo ((struct sockaddr_in6 *)rp->ai_addr)->sin6_port = htons(port); }else{ COMPAT_CLOSE(*sock); + *sock = INVALID_SOCKET; continue; } @@ -346,13 +348,14 @@ int net__try_connect(struct mosquitto *mosq, const char *host, uint16_t port, mo } if(!rp_bind){ COMPAT_CLOSE(*sock); + *sock = INVALID_SOCKET; continue; } } if(!blocking){ /* Set non-blocking */ - if(net__socket_nonblock(*sock)){ + if(net__socket_nonblock(sock)){ continue; } } @@ -368,7 +371,7 @@ int net__try_connect(struct mosquitto *mosq, const char *host, uint16_t port, mo if(blocking){ /* Set non-blocking */ - if(net__socket_nonblock(*sock)){ + if(net__socket_nonblock(sock)){ continue; } } @@ -411,12 +414,10 @@ int net__socket_connect_tls(struct mosquitto *mosq) ret = SSL_connect(mosq->ssl); if(ret != 1) { err = SSL_get_error(mosq->ssl, ret); -#ifdef WIN32 if (err == SSL_ERROR_SYSCALL) { mosq->want_connect = true; return MOSQ_ERR_SUCCESS; } -#endif if(err == SSL_ERROR_WANT_READ){ mosq->want_connect = true; /* We always try to read anyway */ @@ -467,6 +468,7 @@ static int net__init_ssl_ctx(struct mosquitto *mosq) if(!mosq->ssl_ctx){ log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to create TLS context."); COMPAT_CLOSE(mosq->sock); + mosq->sock = INVALID_SOCKET; net__print_ssl_error(mosq); return MOSQ_ERR_TLS; } @@ -483,6 +485,7 @@ static int net__init_ssl_ctx(struct mosquitto *mosq) }else{ log__printf(mosq, MOSQ_LOG_ERR, "Error: Protocol %s not supported.", mosq->tls_version); COMPAT_CLOSE(mosq->sock); + mosq->sock = INVALID_SOCKET; return MOSQ_ERR_INVAL; } @@ -499,6 +502,7 @@ static int net__init_ssl_ctx(struct mosquitto *mosq) if(ret == 0){ log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to set TLS ciphers. Check cipher list \"%s\".", mosq->tls_ciphers); COMPAT_CLOSE(mosq->sock); + mosq->sock = INVALID_SOCKET; net__print_ssl_error(mosq); return MOSQ_ERR_TLS; } @@ -524,6 +528,7 @@ static int net__init_ssl_ctx(struct mosquitto *mosq) } #endif COMPAT_CLOSE(mosq->sock); + mosq->sock = INVALID_SOCKET; net__print_ssl_error(mosq); return MOSQ_ERR_TLS; } @@ -547,6 +552,7 @@ static int net__init_ssl_ctx(struct mosquitto *mosq) log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client certificate \"%s\".", mosq->tls_certfile); #endif COMPAT_CLOSE(mosq->sock); + mosq->sock = INVALID_SOCKET; net__print_ssl_error(mosq); return MOSQ_ERR_TLS; } @@ -560,6 +566,7 @@ static int net__init_ssl_ctx(struct mosquitto *mosq) log__printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client key file \"%s\".", mosq->tls_keyfile); #endif COMPAT_CLOSE(mosq->sock); + mosq->sock = INVALID_SOCKET; net__print_ssl_error(mosq); return MOSQ_ERR_TLS; } @@ -567,6 +574,7 @@ static int net__init_ssl_ctx(struct mosquitto *mosq) if(ret != 1){ log__printf(mosq, MOSQ_LOG_ERR, "Error: Client certificate/key are inconsistent."); COMPAT_CLOSE(mosq->sock); + mosq->sock = INVALID_SOCKET; net__print_ssl_error(mosq); return MOSQ_ERR_TLS; } @@ -595,6 +603,7 @@ int net__socket_connect_step3(struct mosquitto *mosq, const char *host, uint16_t mosq->ssl = SSL_new(mosq->ssl_ctx); if(!mosq->ssl){ COMPAT_CLOSE(mosq->sock); + mosq->sock = INVALID_SOCKET; net__print_ssl_error(mosq); return MOSQ_ERR_TLS; } @@ -603,6 +612,7 @@ int net__socket_connect_step3(struct mosquitto *mosq, const char *host, uint16_t bio = BIO_new_socket(mosq->sock, BIO_NOCLOSE); if(!bio){ COMPAT_CLOSE(mosq->sock); + mosq->sock = INVALID_SOCKET; net__print_ssl_error(mosq); return MOSQ_ERR_TLS; } @@ -613,6 +623,7 @@ int net__socket_connect_step3(struct mosquitto *mosq, const char *host, uint16_t */ if(SSL_set_tlsext_host_name(mosq->ssl, host) != 1) { COMPAT_CLOSE(mosq->sock); + mosq->sock = INVALID_SOCKET; return MOSQ_ERR_TLS; } @@ -639,11 +650,11 @@ int net__socket_connect(struct mosquitto *mosq, const char *host, uint16_t port, rc = net__try_connect(mosq, host, port, &sock, bind_address, blocking); if(rc > 0) return rc; + mosq->sock = sock; + rc = net__socket_connect_step3(mosq, host, port, bind_address, blocking); if(rc) return rc; - mosq->sock = sock; - return MOSQ_ERR_SUCCESS; } @@ -742,25 +753,26 @@ ssize_t net__write(struct mosquitto *mosq, void *buf, size_t count) } -int net__socket_nonblock(mosq_sock_t sock) +int net__socket_nonblock(mosq_sock_t *sock) { #ifndef WIN32 int opt; /* Set non-blocking */ - opt = fcntl(sock, F_GETFL, 0); + opt = fcntl(*sock, F_GETFL, 0); if(opt == -1){ - COMPAT_CLOSE(sock); + COMPAT_CLOSE(*sock); + *sock = INVALID_SOCKET; return MOSQ_ERR_ERRNO; } - if(fcntl(sock, F_SETFL, opt | O_NONBLOCK) == -1){ + if(fcntl(*sock, F_SETFL, opt | O_NONBLOCK) == -1){ /* If either fcntl fails, don't want to allow this client to connect. */ - COMPAT_CLOSE(sock); + COMPAT_CLOSE(*sock); return MOSQ_ERR_ERRNO; } #else unsigned long opt = 1; - if(ioctlsocket(sock, FIONBIO, &opt)){ - COMPAT_CLOSE(sock); + if(ioctlsocket(*sock, FIONBIO, &opt)){ + COMPAT_CLOSE(*sock); return MOSQ_ERR_ERRNO; } #endif @@ -837,7 +849,7 @@ int net__socketpair(mosq_sock_t *pairR, mosq_sock_t *pairW) COMPAT_CLOSE(listensock); continue; } - if(net__socket_nonblock(spR)){ + if(net__socket_nonblock(&spR)){ COMPAT_CLOSE(listensock); continue; } @@ -863,7 +875,7 @@ int net__socketpair(mosq_sock_t *pairR, mosq_sock_t *pairW) } } - if(net__socket_nonblock(spW)){ + if(net__socket_nonblock(&spW)){ COMPAT_CLOSE(spR); COMPAT_CLOSE(listensock); continue; @@ -881,11 +893,11 @@ int net__socketpair(mosq_sock_t *pairR, mosq_sock_t *pairW) if(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1){ return MOSQ_ERR_ERRNO; } - if(net__socket_nonblock(sv[0])){ + if(net__socket_nonblock(&sv[0])){ COMPAT_CLOSE(sv[1]); return MOSQ_ERR_ERRNO; } - if(net__socket_nonblock(sv[1])){ + if(net__socket_nonblock(&sv[1])){ COMPAT_CLOSE(sv[0]); return MOSQ_ERR_ERRNO; } diff --git a/lib/net_mosq.h b/lib/net_mosq.h index b5d85494..8c18c308 100644 --- a/lib/net_mosq.h +++ b/lib/net_mosq.h @@ -62,7 +62,7 @@ int net__try_connect(struct mosquitto *mosq, const char *host, uint16_t port, mo int net__try_connect_step1(struct mosquitto *mosq, const char *host); int net__try_connect_step2(struct mosquitto *mosq, uint16_t port, mosq_sock_t *sock); int net__socket_connect_step3(struct mosquitto *mosq, const char *host, uint16_t port, const char *bind_address, bool blocking); -int net__socket_nonblock(mosq_sock_t sock); +int net__socket_nonblock(mosq_sock_t *sock); int net__socketpair(mosq_sock_t *sp1, mosq_sock_t *sp2); ssize_t net__read(struct mosquitto *mosq, void *buf, size_t count); diff --git a/src/net.c b/src/net.c index 818483e3..1d1e6c15 100644 --- a/src/net.c +++ b/src/net.c @@ -104,7 +104,7 @@ int net__socket_accept(struct mosquitto_db *db, mosq_sock_t listensock) G_SOCKET_CONNECTIONS_INC(); - if(net__socket_nonblock(new_sock)){ + if(net__socket_nonblock(&new_sock)){ return INVALID_SOCKET; } @@ -391,7 +391,7 @@ int net__socket_listen(struct mosquitto__listener *listener) ss_opt = 1; setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &ss_opt, sizeof(ss_opt)); - if(net__socket_nonblock(sock)){ + if(net__socket_nonblock(&sock)){ return 1; }