Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix and improve interface binding #2081

Merged
merged 2 commits into from Mar 11, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
57 changes: 42 additions & 15 deletions src/net.c
Expand Up @@ -624,23 +624,38 @@ static int net__bind_interface(struct mosquitto__listener *listener, struct addr
&& ifa->ifa_addr->sa_family == rp->ai_addr->sa_family){

if(rp->ai_addr->sa_family == AF_INET){
memcpy(&((struct sockaddr_in *)rp->ai_addr)->sin_addr,
&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr,
sizeof(struct in_addr));

freeifaddrs(ifaddr);
return MOSQ_ERR_SUCCESS;
if(listener->host &&
memcmp(&((struct sockaddr_in *)rp->ai_addr)->sin_addr,
&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr,
sizeof(struct in_addr))){
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Interface address does not match specified listener host.");
}else{
memcpy(&((struct sockaddr_in *)rp->ai_addr)->sin_addr,
&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr,
sizeof(struct in_addr));

freeifaddrs(ifaddr);
return MOSQ_ERR_SUCCESS;
}
}else if(rp->ai_addr->sa_family == AF_INET6){
memcpy(&((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr,
&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr,
sizeof(struct in6_addr));
freeifaddrs(ifaddr);
return MOSQ_ERR_SUCCESS;
if(listener->host &&
memcmp(&((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr,
&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr,
sizeof(struct in6_addr))){
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Interface address does not match specified listener host.");
}else{
memcpy(&((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr,
&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr,
sizeof(struct in6_addr));
freeifaddrs(ifaddr);
return MOSQ_ERR_SUCCESS;
}
}
}
}
freeifaddrs(ifaddr);
log__printf(NULL, MOSQ_LOG_ERR, "Error: Interface %s not found.", listener->bind_interface);
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Interface %s does not support %s configuration.",
listener->bind_interface, rp->ai_addr->sa_family == AF_INET ? "ipv4" : "ipv6");
return MOSQ_ERR_NOT_FOUND;
}
#endif
Expand All @@ -654,6 +669,9 @@ static int net__socket_listen_tcp(struct mosquitto__listener *listener)
char service[10];
int rc;
int ss_opt = 1;
#ifndef WIN32
bool interface_bound = false;
#endif

if(!listener) return MOSQ_ERR_INVAL;

Expand Down Expand Up @@ -718,12 +736,14 @@ static int net__socket_listen_tcp(struct mosquitto__listener *listener)

#ifndef WIN32
if(listener->bind_interface){
/* It might be possible that an interface does not support all relevant sa_families.
* We should successfully find at least one. */
if(net__bind_interface(listener, rp)){
COMPAT_CLOSE(sock);
freeaddrinfo(ainfo);
mosquitto__free(listener->socks);
return 1;
listener->sock_count--;
continue;
}
interface_bound = true;
}
#endif

Expand All @@ -745,6 +765,13 @@ static int net__socket_listen_tcp(struct mosquitto__listener *listener)
}
freeaddrinfo(ainfo);

#ifndef WIN32
if(listener->bind_interface && !interface_bound){
mosquitto__free(listener->socks);
return 1;
}
#endif

return 0;
}

Expand Down