|
|
|
@ -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;
|
|
|
|
|
}
|
|
|
|
|