1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

ipv6: force ipv4 if iface bind uses ipv4 address

This commit is contained in:
Andy Green 2019-03-08 08:58:56 +08:00
parent 529b59cf6f
commit b31ab02786
6 changed files with 26 additions and 15 deletions

View file

@ -22,13 +22,14 @@
#include "core/private.h"
#if !defined(LWS_WITH_ESP32) && !defined(LWS_PLAT_OPTEE)
LWS_VISIBLE int
static int
interface_to_sa(struct lws_vhost *vh, const char *ifname,
struct sockaddr_in *addr, size_t addrlen)
struct sockaddr_in *addr, size_t addrlen, int allow_ipv6)
{
int ipv6 = 0;
#ifdef LWS_WITH_IPV6
ipv6 = LWS_IPV6_ENABLED(vh);
if (allow_ipv6)
ipv6 = LWS_IPV6_ENABLED(vh);
#endif
(void)vh;
@ -205,7 +206,7 @@ bail:
LWS_EXTERN int
lws_socket_bind(struct lws_vhost *vhost, lws_sockfd_type sockfd, int port,
const char *iface)
const char *iface, int ipv6_allowed)
{
#ifdef LWS_WITH_UNIX_SOCK
struct sockaddr_un serv_unix;
@ -248,13 +249,13 @@ lws_socket_bind(struct lws_vhost *vhost, lws_sockfd_type sockfd, int port,
} else
#endif
#if defined(LWS_WITH_IPV6) && !defined(LWS_WITH_ESP32)
if (LWS_IPV6_ENABLED(vhost)) {
if (ipv6_allowed && LWS_IPV6_ENABLED(vhost)) {
v = (struct sockaddr *)&serv_addr6;
n = sizeof(struct sockaddr_in6);
bzero((char *) &serv_addr6, sizeof(serv_addr6));
if (iface) {
m = interface_to_sa(vhost, iface,
(struct sockaddr_in *)v, n);
(struct sockaddr_in *)v, n, 1);
if (m == LWS_ITOSA_NOT_USABLE) {
lwsl_info("%s: netif %s: Not usable\n",
__func__, iface);
@ -282,7 +283,7 @@ lws_socket_bind(struct lws_vhost *vhost, lws_sockfd_type sockfd, int port,
#if !defined(LWS_WITH_ESP32) && !defined(LWS_PLAT_OPTEE)
if (iface) {
m = interface_to_sa(vhost, iface,
(struct sockaddr_in *)v, n);
(struct sockaddr_in *)v, n, 0);
if (m == LWS_ITOSA_NOT_USABLE) {
lwsl_info("%s: netif %s: Not usable\n",
__func__, iface);

View file

@ -648,7 +648,7 @@ lws_role_by_name(const char *name);
LWS_EXTERN int
lws_socket_bind(struct lws_vhost *vhost, lws_sockfd_type sockfd, int port,
const char *iface);
const char *iface, int ipv6_allowed);
#if defined(LWS_WITH_IPV6)
LWS_EXTERN unsigned long

View file

@ -472,9 +472,6 @@ lws_b64_selftest(void);
#define get_daemonize_pid() (0)
#endif
LWS_EXTERN int LWS_WARN_UNUSED_RESULT
interface_to_sa(struct lws_vhost *vh, const char *ifname,
struct sockaddr_in *addr, size_t addrlen);
LWS_EXTERN void lwsl_emit_stderr(int level, const char *line);
#if !defined(LWS_WITH_TLS)

View file

@ -210,6 +210,7 @@ lws_interface_to_sa(int ipv6, const char *ifname, struct sockaddr_in *addr,
memcpy(&addr6->sin6_addr.s6_addr[12],
&((struct sockaddr_in *)ifc->ifa_addr)->sin_addr,
sizeof(struct in_addr));
lwsl_debug("%s: uplevelling ipv4 bind to ipv6\n", __func__);
} else
#endif
memcpy(addr,

View file

@ -51,7 +51,7 @@ lws_client_connect_2(struct lws *wsi)
char ipv6only = lws_check_opt(wsi->vhost->options,
LWS_SERVER_OPTION_IPV6_V6ONLY_MODIFY |
LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE);
struct sockaddr_in addr;
#if defined(__ANDROID__)
ipv6only = 0;
#endif
@ -228,6 +228,18 @@ create_new_conn:
* start off allowing ipv6 on connection if vhost allows it
*/
wsi->ipv6 = LWS_IPV6_ENABLED(wsi->vhost);
#ifdef LWS_WITH_IPV6
if (wsi->stash)
iface = wsi->stash->iface;
else
iface = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_IFACE);
if (wsi->ipv6 && iface &&
inet_pton(AF_INET, iface, &addr.sin_addr) == 1) {
lwsl_notice("%s: client connection forced to IPv4\n", __func__);
wsi->ipv6 = 0;
}
#endif
#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
@ -464,7 +476,7 @@ ads_known:
if (iface) {
n = lws_socket_bind(wsi->vhost, wsi->desc.sockfd, 0,
iface);
iface, wsi->ipv6);
if (n < 0) {
cce = "unable to bind socket";
goto failed;

View file

@ -84,7 +84,7 @@ _lws_vhost_init_server(const struct lws_context_creation_info *info,
* of the interface he wants to bind to...
*/
is = lws_socket_bind(vhost, LWS_SOCK_INVALID, vhost->listen_port,
vhost->iface);
vhost->iface, 1);
lwsl_debug("initial if check says %d\n", is);
if (is == LWS_ITOSA_BUSY)
@ -233,7 +233,7 @@ done_list:
#endif
lws_plat_set_socket_options(vhost, sockfd, 0);
is = lws_socket_bind(vhost, sockfd, vhost->listen_port, vhost->iface);
is = lws_socket_bind(vhost, sockfd, vhost->listen_port, vhost->iface, 1);
if (is == LWS_ITOSA_BUSY) {
/* treat as fatal */
compatible_close(sockfd);