mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
Merge branch 'warmcat:main' into main
This commit is contained in:
commit
a2d51ba952
33 changed files with 633 additions and 105 deletions
|
@ -326,6 +326,7 @@ option(LWS_HTTP_HEADERS_ALL "Override header reduction optimization and include
|
|||
option(LWS_WITH_SUL_DEBUGGING "Enable zombie lws_sul checking on object deletion" OFF)
|
||||
option(LWS_WITH_PLUGINS_API "Build generic lws_plugins apis (see LWS_WITH_PLUGINS to also build protocol plugins)" OFF)
|
||||
option(LWS_WITH_CONMON "Collect introspectable connection latency stats on individual client connections" ON)
|
||||
option(LWS_WITH_WOL "Wake On Lan support" ON)
|
||||
option(LWS_WITHOUT_EVENTFD "Force using pipe instead of eventfd" OFF)
|
||||
if (UNIX OR WIN32)
|
||||
option(LWS_WITH_CACHE_NSCOOKIEJAR "Build file-backed lws-cache-ttl that uses netscape cookie jar format (linux-only)" ON)
|
||||
|
@ -658,6 +659,7 @@ CHECK_C_SOURCE_COMPILES("#include <malloc.h>\nvoid main(void) { while(1) ; } voi
|
|||
CHECK_C_SOURCE_COMPILES("#include <pthread.h>\nvoid main(void) { while(1) ; } void xxexit(void){}" LWS_HAVE_PTHREAD_H)
|
||||
CHECK_C_SOURCE_COMPILES("#include <inttypes.h>\nvoid main(void) { while(1) ; } void xxexit(void){}" LWS_HAVE_INTTYPES_H)
|
||||
CHECK_C_SOURCE_COMPILES("#include <sys/resource.h>\nvoid main(void) { while(1) ; } void xxexit(void){}" LWS_HAVE_SYS_RESOURCE_H)
|
||||
CHECK_C_SOURCE_COMPILES("#include <linux/ipv6.h>\nvoid main(void) { while(1) ; } void xxexit(void){}" LWS_HAVE_LINUX_IPV6_H)
|
||||
|
||||
if (LWS_EXT_PTHREAD_INCLUDE_DIR)
|
||||
set(LWS_HAVE_PTHREAD_H 1)
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
#cmakedefine LWS_HAVE_mbedtls_ssl_set_verify
|
||||
#cmakedefine LWS_HAVE_mbedtls_x509_crt_parse_file
|
||||
#cmakedefine LWS_HAVE_MBEDTLS_NET_SOCKETS
|
||||
#cmakedefine LWS_HAVE_MBEDTLS_SSL_NEW_SESSION_TICKET
|
||||
#cmakedefine LWS_HAVE_MBEDTLS_AUTH_KEY_ID
|
||||
#cmakedefine LWS_HAVE_NEW_UV_VERSION_H
|
||||
#cmakedefine LWS_HAVE_OPENSSL_ECDH_H
|
||||
|
@ -258,4 +259,4 @@
|
|||
#cmakedefine LWS_WITH_PLUGINS_API
|
||||
#cmakedefine LWS_HAVE_RTA_PREF
|
||||
#cmakedefine PICO_SDK_PATH
|
||||
|
||||
#cmakedefine LWS_HAVE_LINUX_IPV6_H
|
||||
|
|
|
@ -146,7 +146,7 @@ typedef int suseconds_t;
|
|||
#include <sys/capability.h>
|
||||
#endif
|
||||
|
||||
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__QNX__) || defined(__OpenBSD__)
|
||||
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__QNX__) || defined(__OpenBSD__) || defined(__NuttX__)
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
|
|
@ -56,6 +56,11 @@ enum lws_client_connect_ssl_connection_flags {
|
|||
* then it is not possible to bind to this port for any local address
|
||||
*/
|
||||
|
||||
LCCSCF_IPV6_PREFER_PUBLIC_ADDR = (1 << 15),
|
||||
/**< RFC5014 - For IPv6 systems with SLAAC config, allow for preference
|
||||
* to bind a socket to public address vs temporary private address
|
||||
*/
|
||||
|
||||
LCCSCF_PIPELINE = (1 << 16),
|
||||
/**< Serialize / pipeline multiple client connections
|
||||
* on a single connection where possible.
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
* lws display_list and display_list objects (dlo)
|
||||
*/
|
||||
|
||||
#if !defined(__LWS_DLO_H__)
|
||||
#define __LWS_DLO_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct lws_display_render_state;
|
||||
|
@ -267,8 +270,6 @@ typedef struct {
|
|||
char failed;
|
||||
} lws_dlo_image_t;
|
||||
|
||||
typedef struct lws_display_state lws_display_state_t;
|
||||
|
||||
typedef struct lws_displaylist {
|
||||
lws_dll2_owner_t dl;
|
||||
struct lws_display_state *ds;
|
||||
|
@ -287,7 +288,7 @@ typedef struct lws_display_render_stack {
|
|||
|
||||
typedef struct lws_display_render_state {
|
||||
lws_sorted_usec_list_t sul; /* return to event loop statefully */
|
||||
lws_display_state_t *lds; /* optional, if using lws_display */
|
||||
struct lws_display_state *lds; /* optional, if using lws_display */
|
||||
|
||||
lws_dll2_owner_t ids;
|
||||
|
||||
|
@ -460,13 +461,11 @@ typedef struct {
|
|||
LWS_VISIBLE LWS_EXTERN int
|
||||
lws_dlo_ss_create(lws_dlo_ss_create_info_t *i, lws_dlo_t **pdlo);
|
||||
|
||||
typedef struct lhp_ctx lhp_ctx_t;
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN int
|
||||
lws_dlo_ss_find(struct lws_context *cx, const char *url, lws_dlo_image_t *u);
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN lws_stateful_ret_t
|
||||
lhp_displaylist_layout(lhp_ctx_t *ctx, char reason);
|
||||
lhp_displaylist_layout(struct lhp_ctx *ctx, char reason);
|
||||
|
||||
#define lws_dlo_image_width(_u) ((_u)->failed ? -1 : \
|
||||
((_u)->type == LWSDLOSS_TYPE_JPEG ? \
|
||||
|
@ -522,3 +521,4 @@ LWS_VISIBLE LWS_EXTERN void
|
|||
lws_dlo_file_destroy(struct lws_context *cx);
|
||||
|
||||
LWS_VISIBLE extern const struct lws_plat_file_ops lws_dlo_fops;
|
||||
#endif
|
||||
|
|
|
@ -1250,3 +1250,15 @@ lws_minilex_parse(const uint8_t *lex, int16_t *ps, const uint8_t c,
|
|||
|
||||
LWS_VISIBLE LWS_EXTERN unsigned int
|
||||
lws_sigbits(uintptr_t u);
|
||||
|
||||
/**
|
||||
* lws_wol() - broadcast a magic WOL packet to MAC, optionally binding to if IP
|
||||
*
|
||||
* \p ctx: The lws context
|
||||
* \p ip_or_NULL: The IP address to bind to at the client side, to send the
|
||||
* magic packet on. If NULL, the system chooses, probably the
|
||||
* interface with the default route.
|
||||
* \p mac_6_bytes: Points to a 6-byte MAC address to direct the magic packet to
|
||||
*/
|
||||
LWS_VISIBLE LWS_EXTERN int
|
||||
lws_wol(struct lws_context *ctx, const char *ip_or_NULL, uint8_t *mac_6_bytes);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* libwebsockets - small server side websockets and web server implementation
|
||||
*
|
||||
* Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
|
||||
* Copyright (C) 2010 - 2023 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
|
@ -246,4 +246,16 @@ lws_write_numeric_address(const uint8_t *ads, int size, char *buf, size_t len);
|
|||
LWS_VISIBLE LWS_EXTERN int
|
||||
lws_sa46_write_numeric_address(lws_sockaddr46 *sa46, char *buf, size_t len);
|
||||
|
||||
/**
|
||||
* lws_parse_mac() - convert XX:XX:XX:XX:XX:XX to 6-byte MAC address
|
||||
*
|
||||
* \param ads: mac address as XX:XX:XX:XX:XX:XX string
|
||||
* \param result_6_bytes: result buffer to take 6 bytes
|
||||
*
|
||||
* Converts a string representation of a 6-byte hex mac address to a 6-byte
|
||||
* array.
|
||||
*/
|
||||
LWS_VISIBLE LWS_EXTERN int
|
||||
lws_parse_mac(const char *ads, uint8_t *result_6_bytes);
|
||||
|
||||
///@}
|
||||
|
|
|
@ -371,6 +371,8 @@ if (DEFINED LWS_PLAT_UNIX)
|
|||
endif()
|
||||
endif()
|
||||
set(LWS_HAVE_MBEDTLS_NET_SOCKETS ${LWS_HAVE_MBEDTLS_NET_SOCKETS} PARENT_SCOPE)
|
||||
set(LWS_HAVE_MBEDTLS_SSL_NEW_SESSION_TICKET ${LWS_HAVE_MBEDTLS_SSL_NEW_SESSION_TICKET} PARENT_SCOPE)
|
||||
set(LWS_HAVE_mbedtls_ssl_conf_alpn_protocols ${LWS_HAVE_mbedtls_ssl_conf_alpn_protocols} PARENT_SCOPE)
|
||||
set(TEST_SERVER_SSL_KEY "${TEST_SERVER_SSL_KEY}" PARENT_SCOPE)
|
||||
set(TEST_SERVER_SSL_CERT "${TEST_SERVER_SSL_CERT}" PARENT_SCOPE)
|
||||
set(TEST_SERVER_DATA ${TEST_SERVER_DATA} PARENT_SCOPE)
|
||||
|
|
|
@ -56,6 +56,11 @@ if (LWS_WITH_LWS_DSH)
|
|||
core-net/lws-dsh.c)
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_WOL)
|
||||
list(APPEND SOURCES
|
||||
core-net/wol.c)
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_CLIENT)
|
||||
list(APPEND SOURCES
|
||||
core-net/client/client.c
|
||||
|
|
|
@ -1104,3 +1104,62 @@ lws_system_get_state_manager(struct lws_context *context)
|
|||
return &context->mgr_system;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
lws_parse_mac(const char *ads, uint8_t *result_6_bytes)
|
||||
{
|
||||
uint8_t *p = result_6_bytes;
|
||||
struct lws_tokenize ts;
|
||||
char t[3];
|
||||
size_t n;
|
||||
long u;
|
||||
|
||||
lws_tokenize_init(&ts, ads, LWS_TOKENIZE_F_NO_INTEGERS |
|
||||
LWS_TOKENIZE_F_MINUS_NONTERM);
|
||||
ts.len = strlen(ads);
|
||||
|
||||
do {
|
||||
ts.e = (int8_t)lws_tokenize(&ts);
|
||||
switch (ts.e) {
|
||||
case LWS_TOKZE_TOKEN:
|
||||
if (ts.token_len != 2)
|
||||
return -1;
|
||||
if (p - result_6_bytes == 6)
|
||||
return -2;
|
||||
t[0] = ts.token[0];
|
||||
t[1] = ts.token[1];
|
||||
t[2] = '\0';
|
||||
for (n = 0; n < 2; n++)
|
||||
if (t[n] < '0' || t[n] > 'f' ||
|
||||
(t[n] > '9' && t[n] < 'A') ||
|
||||
(t[n] > 'F' && t[n] < 'a'))
|
||||
return -1;
|
||||
u = strtol(t, NULL, 16);
|
||||
if (u > 0xff)
|
||||
return -5;
|
||||
*p++ = (uint8_t)u;
|
||||
break;
|
||||
|
||||
case LWS_TOKZE_DELIMITER:
|
||||
if (*ts.token != ':')
|
||||
return -10;
|
||||
if (p - result_6_bytes > 5)
|
||||
return -11;
|
||||
break;
|
||||
|
||||
case LWS_TOKZE_ENDED:
|
||||
if (p - result_6_bytes != 6)
|
||||
return -12;
|
||||
return 0;
|
||||
|
||||
default:
|
||||
lwsl_err("%s: malformed mac\n", __func__);
|
||||
|
||||
return -13;
|
||||
}
|
||||
} while (ts.e > 0);
|
||||
|
||||
lwsl_err("%s: ended on e %d\n", __func__, ts.e);
|
||||
|
||||
return -14;
|
||||
}
|
||||
|
|
84
lib/core-net/wol.c
Normal file
84
lib/core-net/wol.c
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* libwebsockets - small server side websockets and web server implementation
|
||||
*
|
||||
* Copyright (C) 2010 - 2023 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "private-lib-core.h"
|
||||
|
||||
int
|
||||
lws_wol(struct lws_context *ctx, const char *ip_or_NULL, uint8_t *mac_6_bytes)
|
||||
{
|
||||
int n, m, ofs = 0, fd, optval = 1, ret = 1;
|
||||
uint8_t pkt[17 * IFHWADDRLEN];
|
||||
struct sockaddr_in addr;
|
||||
|
||||
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (fd < 0) {
|
||||
lwsl_cx_err(ctx, "failed to open UDP, errno %d\n", errno);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
|
||||
(char *)&optval, sizeof(optval)) < 0) {
|
||||
lwsl_cx_err(ctx, "failed to set broadcast, errno %d\n", errno);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lay out the magic packet
|
||||
*/
|
||||
|
||||
for (n = 0; n < IFHWADDRLEN; n++)
|
||||
pkt[ofs++] = 0xff;
|
||||
for (m = 0; m < 16; m++)
|
||||
for (n = 0; n < IFHWADDRLEN; n++)
|
||||
pkt[ofs++] = mac_6_bytes[n];
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(9);
|
||||
|
||||
if (!inet_aton(ip_or_NULL ? ip_or_NULL : "255.255.255.255",
|
||||
&addr.sin_addr)) {
|
||||
lwsl_cx_err(ctx, "failed to convert broadcast ads, errno %d\n",
|
||||
errno);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
lwsl_cx_notice(ctx, "Sending WOL to %02X:%02X:%02X:%02X:%02X:%02X %s\n",
|
||||
mac_6_bytes[0], mac_6_bytes[1], mac_6_bytes[2], mac_6_bytes[3],
|
||||
mac_6_bytes[4], mac_6_bytes[5], ip_or_NULL ? ip_or_NULL : "");
|
||||
|
||||
if (sendto(fd, pkt, sizeof(pkt), 0, (struct sockaddr *)&addr,
|
||||
sizeof(addr)) < 0) {
|
||||
lwsl_cx_err(ctx, "failed to sendto broadcast ads, errno %d\n",
|
||||
errno);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
bail:
|
||||
close(fd);
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -39,7 +39,9 @@ lws_buflist_append_segment(struct lws_buflist **head, const uint8_t *buf,
|
|||
void *p = *head;
|
||||
int sanity = 1024;
|
||||
|
||||
assert(buf);
|
||||
if (!buf)
|
||||
return -1;
|
||||
|
||||
assert(len);
|
||||
|
||||
/* append at the tail */
|
||||
|
|
|
@ -347,10 +347,6 @@ static const char * const opts_str =
|
|||
#if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
|
||||
"SSPROX "
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_MBEDTLS)
|
||||
"MbedTLS "
|
||||
#endif
|
||||
#if defined(LWS_WITH_CONMON)
|
||||
"ConMon "
|
||||
#endif
|
||||
|
@ -410,6 +406,9 @@ lws_create_context(const struct lws_context_creation_info *info)
|
|||
#if defined(LWS_WITH_CACHE_NSCOOKIEJAR) && defined(LWS_WITH_CLIENT)
|
||||
struct lws_cache_creation_info ci;
|
||||
#endif
|
||||
#if defined(LWS_WITH_MBEDTLS)
|
||||
char mbedtls_version[32];
|
||||
#endif
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
struct rlimit rt;
|
||||
|
@ -809,7 +808,16 @@ lws_create_context(const struct lws_context_creation_info *info)
|
|||
|
||||
#endif /* network */
|
||||
|
||||
#if defined(LWS_WITH_MBEDTLS)
|
||||
mbedtls_version_get_string(mbedtls_version);
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_MBEDTLS)
|
||||
lwsl_cx_notice(context, "LWS: %s, MbedTLS-%s %s%s", library_version, mbedtls_version, opts_str, s);
|
||||
#else
|
||||
lwsl_cx_notice(context, "LWS: %s, %s%s", library_version, opts_str, s);
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_NETWORK)
|
||||
lwsl_cx_info(context, "Event loop: %s", plev->ops->name);
|
||||
#endif
|
||||
|
@ -963,7 +971,7 @@ lws_create_context(const struct lws_context_creation_info *info)
|
|||
|
||||
context->options = info->options;
|
||||
|
||||
#if !defined(LWS_PLAT_FREERTOS) && !defined(LWS_PLAT_OPTEE) && !defined(WIN32) && !defined(LWS_PLAT_BAREMETAL)
|
||||
#if defined(LWS_HAVE_SYS_RESOURCE_H) && !defined(LWS_PLAT_FREERTOS) && !defined(LWS_PLAT_OPTEE) && !defined(WIN32) && !defined(LWS_PLAT_BAREMETAL)
|
||||
/*
|
||||
* If asked, try to set the rlimit / ulimit for process sockets / files.
|
||||
* We read the effective limit in a moment, so we will find out the
|
||||
|
|
|
@ -114,7 +114,7 @@ lws_b64_decode_stateful(struct lws_b64state *s, const char *in, size_t *in_len,
|
|||
uint8_t *orig_out = out, *end_out = out + *out_size;
|
||||
int equals = 0;
|
||||
|
||||
while (in < end_in && *in && out + 4 < end_out) {
|
||||
while (in < end_in && *in && out + 3 <= end_out) {
|
||||
|
||||
for (; s->i < 4 && in < end_in && *in; s->i++) {
|
||||
uint8_t v;
|
||||
|
|
|
@ -123,7 +123,7 @@ typedef pthread_mutex_t lws_mutex_t;
|
|||
|
||||
#endif
|
||||
|
||||
#if defined (__sun) || defined(__HAIKU__) || defined(__QNX__) || defined(__ANDROID__)
|
||||
#if defined (__sun) || defined(__HAIKU__) || defined(__QNX__) || defined(__ANDROID__) || defined(__NuttX__)
|
||||
#include <syslog.h>
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* libwebsockets - small server side websockets and web server implementation
|
||||
*
|
||||
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
|
||||
* Copyright (C) 2010 - 2023 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
|
@ -27,6 +27,10 @@
|
|||
#endif
|
||||
#include "private-lib-core.h"
|
||||
|
||||
#if defined(LWS_HAVE_LINUX_IPV6_H)
|
||||
#include <linux/ipv6.h>
|
||||
#endif
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#if !defined(LWS_DETECTED_PLAT_IOS)
|
||||
|
@ -171,7 +175,7 @@ lws_plat_set_socket_options(struct lws_vhost *vhost, int fd, int unix_skt)
|
|||
|
||||
/* Disable Nagle */
|
||||
optval = 1;
|
||||
#if defined (__sun) || defined(__QNX__)
|
||||
#if defined (__sun) || defined(__QNX__) || defined(__NuttX__)
|
||||
if (!unix_skt && setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const void *)&optval, optlen) < 0)
|
||||
return 1;
|
||||
#elif !defined(__APPLE__) && \
|
||||
|
@ -190,6 +194,7 @@ lws_plat_set_socket_options(struct lws_vhost *vhost, int fd, int unix_skt)
|
|||
return lws_plat_set_nonblocking(fd);
|
||||
}
|
||||
|
||||
#if !defined(__NuttX__)
|
||||
static const int ip_opt_lws_flags[] = {
|
||||
LCCSCF_IP_LOW_LATENCY, LCCSCF_IP_HIGH_THROUGHPUT,
|
||||
LCCSCF_IP_HIGH_RELIABILITY
|
||||
|
@ -210,6 +215,7 @@ static const char *ip_opt_names[] = {
|
|||
#endif
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int
|
||||
lws_plat_set_socket_options_ip(lws_sockfd_type fd, uint8_t pri, int lws_flags)
|
||||
|
@ -237,7 +243,8 @@ lws_plat_set_socket_options_ip(lws_sockfd_type fd, uint8_t pri, int lws_flags)
|
|||
!defined(__sun) && \
|
||||
!defined(__HAIKU__) && \
|
||||
!defined(__CYGWIN__) && \
|
||||
!defined(__QNX__)
|
||||
!defined(__QNX__) && \
|
||||
!defined(__NuttX__)
|
||||
|
||||
/* the BSDs don't have SO_PRIORITY */
|
||||
|
||||
|
@ -270,6 +277,27 @@ lws_plat_set_socket_options_ip(lws_sockfd_type fd, uint8_t pri, int lws_flags)
|
|||
}
|
||||
|
||||
|
||||
if (lws_flags & LCCSCF_IPV6_PREFER_PUBLIC_ADDR) {
|
||||
#if defined(LWS_WITH_IPV6) && defined(IPV6_PREFER_SRC_PUBLIC)
|
||||
optval = IPV6_PREFER_SRC_PUBLIC;
|
||||
|
||||
if (setsockopt(fd, IPPROTO_IPV6, IPV6_ADDR_PREFERENCES,
|
||||
(const void *)&optval, optlen) < 0) {
|
||||
#if (_LWS_ENABLED_LOGS & LLL_WARN)
|
||||
en = errno;
|
||||
lwsl_warn("%s: unable to set IPV6_PREFER_SRC_PUBLIC: errno %d\n",
|
||||
__func__, en);
|
||||
#endif
|
||||
ret = 1;
|
||||
} else
|
||||
lwsl_notice("%s: set IPV6_PREFER_SRC_PUBLIC\n", __func__);
|
||||
#else
|
||||
lwsl_err("%s: IPV6_PREFER_SRC_PUBLIC UNIMPLEMENTED on this platform\n", __func__);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if !defined(__NuttX__)
|
||||
for (n = 0; n < 4; n++) {
|
||||
if (!(lws_flags & ip_opt_lws_flags[n]))
|
||||
continue;
|
||||
|
@ -287,6 +315,7 @@ lws_plat_set_socket_options_ip(lws_sockfd_type fd, uint8_t pri, int lws_flags)
|
|||
lwsl_notice("%s: set ip flag %s\n", __func__,
|
||||
ip_opt_names[n]);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -193,6 +193,16 @@ lws_plat_set_socket_options_ip(lws_sockfd_type fd, uint8_t pri, int lws_flags)
|
|||
} else
|
||||
lwsl_notice("%s: set use exclusive addresses\n", __func__);
|
||||
}
|
||||
|
||||
|
||||
#if defined(LWS_WITH_IPV6)
|
||||
/* I do not believe Microsoft supports RFC5014
|
||||
* Instead, you must set lws_client_connect_info::iface */
|
||||
if (lws_flags & LCCSCF_IPV6_PREFER_PUBLIC_ADDR) {
|
||||
lwsl_err("%s: UNIMPLEMENTED on this platform\n", __func__);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -534,7 +534,7 @@ lws_h2_settings(struct lws *wsi, struct http2_settings *settings,
|
|||
case H2SET_INITIAL_WINDOW_SIZE:
|
||||
if (b > 0x7fffffff) {
|
||||
lws_h2_goaway(nwsi, H2_ERR_FLOW_CONTROL_ERROR,
|
||||
"Inital Window beyond max");
|
||||
"Initial Window beyond max");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1618,7 +1618,7 @@ lws_h2_parse_end_of_frame(struct lws *wsi)
|
|||
|
||||
if (!h2n->swsi->h2.END_HEADERS) {
|
||||
/* we are not finished yet */
|
||||
lwsl_info("witholding http action for continuation\n");
|
||||
lwsl_info("withholding http action for continuation\n");
|
||||
h2n->cont_exp_sid = h2n->sid;
|
||||
h2n->cont_exp = 1;
|
||||
break;
|
||||
|
@ -2816,7 +2816,6 @@ int
|
|||
lws_read_h2(struct lws *wsi, unsigned char *buf, lws_filepos_t len)
|
||||
{
|
||||
unsigned char *oldbuf = buf;
|
||||
lws_filepos_t body_chunk_len;
|
||||
|
||||
// lwsl_notice("%s: h2 path: wsistate 0x%x len %d\n", __func__,
|
||||
// wsi->wsistate, (int)len);
|
||||
|
@ -2832,6 +2831,7 @@ lws_read_h2(struct lws *wsi, unsigned char *buf, lws_filepos_t len)
|
|||
* case.
|
||||
*/
|
||||
while (len) {
|
||||
lws_filepos_t body_chunk_len = 0;
|
||||
int m;
|
||||
|
||||
/*
|
||||
|
|
|
@ -41,7 +41,8 @@
|
|||
#define RTA_ALIGNTO 4U
|
||||
|
||||
//#define lwsl_netlink lwsl_notice
|
||||
#define lwsl_cx_netlink lwsl_cx_info
|
||||
#define lwsl_cx_netlink lwsl_cx_info
|
||||
#define lwsl_cx_netlink_debug lwsl_cx_debug
|
||||
|
||||
static void
|
||||
lws_netlink_coldplug_done_cb(lws_sorted_usec_list_t *sul)
|
||||
|
@ -69,11 +70,11 @@ rops_handle_POLLIN_netlink(struct lws_context_per_thread *pt, struct lws *wsi,
|
|||
#endif
|
||||
;
|
||||
struct sockaddr_nl nladdr;
|
||||
lws_route_t robj, *rou, *rmat;
|
||||
lws_route_t robj, *rou;
|
||||
struct nlmsghdr *h;
|
||||
struct msghdr msg;
|
||||
struct iovec iov;
|
||||
unsigned int n;
|
||||
unsigned int n, removed;
|
||||
char buf[72];
|
||||
|
||||
if (!(pollfd->revents & LWS_POLLIN))
|
||||
|
@ -190,8 +191,50 @@ rops_handle_POLLIN_netlink(struct lws_context_per_thread *pt, struct lws *wsi,
|
|||
ra_len = (unsigned int)IFA_PAYLOAD(h);
|
||||
|
||||
lwsl_cx_netlink(cx, "%s",
|
||||
h->nlmsg_type == RTM_NEWADDR ?
|
||||
"NEWADDR" : "DELADDR");
|
||||
h->nlmsg_type == RTM_NEWADDR ? "NEWADDR" : "DELADDR");
|
||||
|
||||
// Parse attributes.
|
||||
for ( ; RTA_OK(ra, ra_len); ra = RTA_NEXT(ra, ra_len)) {
|
||||
//lwsl_cx_netlink_debug(cx, "%s: IFA %d\n", __func__, ra->rta_type);
|
||||
switch (ra->rta_type) {
|
||||
case IFA_LOCAL:
|
||||
// Local address
|
||||
lws_sa46_copy_address(&robj.src, RTA_DATA(ra), rm->rtm_family);
|
||||
robj.src_len = rm->rtm_src_len;
|
||||
lws_sa46_write_numeric_address(&robj.src, buf, sizeof(buf));
|
||||
lwsl_cx_netlink_debug(cx, "IFA_LOCAL: %s/%d", buf, robj.src_len);
|
||||
break;
|
||||
case IFA_ADDRESS:
|
||||
// Prefix address, not local interface.
|
||||
lws_sa46_copy_address(&robj.dest, RTA_DATA(ra), rm->rtm_family);
|
||||
robj.dest_len = rm->rtm_dst_len;
|
||||
lws_sa46_write_numeric_address(&robj.dest, buf, sizeof(buf));
|
||||
lwsl_cx_netlink_debug(cx, "IFA_ADDRESS: %s/%d", buf, robj.dest_len);
|
||||
break;
|
||||
case IFA_FLAGS:
|
||||
lwsl_cx_netlink_debug(cx, "IFA_FLAGS: 0x%x (not handled)",
|
||||
*(unsigned int*)RTA_DATA(ra));
|
||||
break;
|
||||
case IFA_BROADCAST:
|
||||
lwsl_cx_netlink_debug(cx, "IFA_BROADCAST (not handled)");
|
||||
break;
|
||||
case IFA_ANYCAST:
|
||||
lwsl_cx_netlink_debug(cx, "IFA_ANYCAST (not handled)");
|
||||
break;
|
||||
case IFA_CACHEINFO:
|
||||
lwsl_cx_netlink_debug(cx, "IFA_CACHEINFO (not handled)");
|
||||
break;
|
||||
case IFA_LABEL:
|
||||
strncpy(buf, RTA_DATA(ra), sizeof(buf));
|
||||
buf[sizeof(buf)-1] = '\0';
|
||||
lwsl_cx_netlink_debug(cx, "IFA_LABEL: %s (not used)", buf);
|
||||
break;
|
||||
default:
|
||||
lwsl_cx_netlink_debug(cx, "unknown IFA attr type %d", ra->rta_type);
|
||||
break;
|
||||
}
|
||||
//lwsl_cx_debug(cx, "rta payload length: %ld", RTA_PAYLOAD(ra));
|
||||
} /* for */
|
||||
|
||||
/*
|
||||
* almost nothing interesting within IFA_* attributes:
|
||||
|
@ -256,7 +299,10 @@ rops_handle_POLLIN_netlink(struct lws_context_per_thread *pt, struct lws *wsi,
|
|||
rm->rtm_family);
|
||||
robj.src_len = rm->rtm_src_len;
|
||||
lws_sa46_write_numeric_address(&robj.src, buf, sizeof(buf));
|
||||
lwsl_cx_netlink(cx, "RTA_SRC: %s", buf);
|
||||
if (ra->rta_type == RTA_SRC)
|
||||
lwsl_cx_netlink_debug(cx, "RTA_SRC: %s/%d", buf, robj.src_len);
|
||||
else
|
||||
lwsl_cx_netlink_debug(cx, "RTA_PREFSRC: %s/%d", buf, robj.src_len);
|
||||
break;
|
||||
case RTA_DST:
|
||||
/* check if is local addr -> considering it as src addr too */
|
||||
|
@ -265,19 +311,21 @@ rops_handle_POLLIN_netlink(struct lws_context_per_thread *pt, struct lws *wsi,
|
|||
(rm->rtm_family == AF_INET6 && rm->rtm_dst_len == 128))) {
|
||||
lws_sa46_copy_address(&robj.src, RTA_DATA(ra),
|
||||
rm->rtm_family);
|
||||
lwsl_cx_netlink(cx, "Local addr: RTA_DST -> added to RTA_SRC");
|
||||
lwsl_cx_netlink_debug(cx, "Local addr: RTA_DST -> added to RTA_SRC");
|
||||
}
|
||||
|
||||
lws_sa46_copy_address(&robj.dest, RTA_DATA(ra),
|
||||
rm->rtm_family);
|
||||
rm->rtm_family);
|
||||
robj.dest_len = rm->rtm_dst_len;
|
||||
lws_sa46_write_numeric_address(&robj.dest, buf, sizeof(buf));
|
||||
lwsl_cx_netlink(cx, "RTA_DST: %s", buf);
|
||||
lwsl_cx_netlink_debug(cx, "RTA_DST: %s/%d", buf, robj.dest_len);
|
||||
break;
|
||||
case RTA_GATEWAY:
|
||||
lws_sa46_copy_address(&robj.gateway,
|
||||
RTA_DATA(ra),
|
||||
lws_sa46_copy_address(&robj.gateway, RTA_DATA(ra),
|
||||
rm->rtm_family);
|
||||
|
||||
lws_sa46_write_numeric_address(&robj.gateway, buf, sizeof(buf));
|
||||
lwsl_cx_netlink_debug(cx, "RTA_GATEWAY: %s", buf);
|
||||
#if defined(LWS_WITH_SYS_SMD)
|
||||
gateway_change = 1;
|
||||
#endif
|
||||
|
@ -285,27 +333,31 @@ rops_handle_POLLIN_netlink(struct lws_context_per_thread *pt, struct lws *wsi,
|
|||
case RTA_IIF: /* int: input interface index */
|
||||
case RTA_OIF: /* int: output interface index */
|
||||
robj.if_idx = *(int *)RTA_DATA(ra);
|
||||
lwsl_cx_netlink(cx, "ifidx %d", robj.if_idx);
|
||||
lwsl_cx_netlink_debug(cx, "RTA_IIF/RTA_OIF: %d", robj.if_idx);
|
||||
break;
|
||||
case RTA_PRIORITY: /* int: priority of route */
|
||||
p = RTA_DATA(ra);
|
||||
robj.priority = p[3] << 24 | p[2] << 16 |
|
||||
p[1] << 8 | p[0];
|
||||
lwsl_cx_netlink_debug(cx, "RTA_PRIORITY: %d", robj.priority);
|
||||
break;
|
||||
case RTA_CACHEINFO: /* struct rta_cacheinfo */
|
||||
lwsl_cx_netlink_debug(cx, "RTA_CACHEINFO (not handled)");
|
||||
break;
|
||||
#if defined(LWS_HAVE_RTA_PREF)
|
||||
case RTA_PREF: /* char: RFC4191 v6 router preference */
|
||||
lwsl_cx_netlink_debug(cx, "RTA_PREF (not handled)");
|
||||
break;
|
||||
#endif
|
||||
case RTA_TABLE: /* int */
|
||||
lwsl_cx_netlink_debug(cx, "RTA_TABLE (not handled)");
|
||||
break;
|
||||
|
||||
default:
|
||||
lwsl_cx_info(cx, "unknown attr type %d",
|
||||
ra->rta_type);
|
||||
lwsl_cx_netlink_debug(cx, "unknown attr type %d", ra->rta_type);
|
||||
break;
|
||||
}
|
||||
//lwsl_cx_debug(cx, "rta payload length: %ld", RTA_PAYLOAD(ra));
|
||||
} /* for */
|
||||
|
||||
/*
|
||||
|
@ -327,83 +379,80 @@ second_half:
|
|||
|
||||
case RTM_NEWROUTE:
|
||||
|
||||
lwsl_cx_netlink(cx, "NEWROUTE rtm_type %d",
|
||||
rm->rtm_type);
|
||||
|
||||
/*
|
||||
* We don't want any routing debris like /32 or broadcast
|
||||
* in our routing table... we will collect source addresses
|
||||
* bound to interfaces via NEWADDR
|
||||
*/
|
||||
|
||||
if (rm->rtm_type != RTN_UNICAST &&
|
||||
rm->rtm_type != RTN_LOCAL)
|
||||
if (rm->rtm_type != RTN_UNICAST
|
||||
&& rm->rtm_type != RTN_LOCAL) {
|
||||
lwsl_cx_netlink(cx, "NEWROUTE: IGNORED (%s)",
|
||||
rm->rtm_type == RTN_BROADCAST ? "broadcast" :
|
||||
rm->rtm_type == RTN_ANYCAST ? "anycast" :
|
||||
rm->rtm_type == RTN_MULTICAST ? "multicast" :
|
||||
rm->rtm_type == RTN_UNREACHABLE ? "unreachable" :
|
||||
rm->rtm_type == RTN_NAT ? "nat" :
|
||||
rm->rtm_type == RTN_UNSPEC ? "unspecified" :
|
||||
"other");
|
||||
break;
|
||||
}
|
||||
|
||||
if (rm->rtm_flags & RTM_F_CLONED)
|
||||
if (rm->rtm_flags & RTM_F_CLONED) {
|
||||
lwsl_cx_netlink(cx, "NEWROUTE: IGNORED (cloned)");
|
||||
break;
|
||||
}
|
||||
|
||||
goto ana;
|
||||
lwsl_cx_netlink(cx, "NEWROUTE: ACCEPTED (if_idx %d)",
|
||||
robj.if_idx);
|
||||
|
||||
case RTM_DELADDR:
|
||||
lwsl_cx_notice(cx, "DELADDR");
|
||||
#if defined(_DEBUG)
|
||||
_lws_routing_entry_dump(cx, &robj);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 1. Allocate new route for linked-list.
|
||||
* (robj is on stack, do NOT use)
|
||||
*/
|
||||
rou = lws_malloc(sizeof(*rou), __func__);
|
||||
if (!rou) {
|
||||
lwsl_cx_err(cx, "oom");
|
||||
return LWS_HPI_RET_HANDLED;
|
||||
}
|
||||
*rou = robj;
|
||||
|
||||
// 2. Remove duplicates and add route (both under a lock).
|
||||
lws_pt_lock(pt, __func__);
|
||||
_lws_route_remove(pt, &robj, LRR_MATCH_SRC | LRR_IGNORE_PRI);
|
||||
_lws_route_pt_close_unroutable(pt);
|
||||
lws_pt_unlock(pt);
|
||||
break;
|
||||
|
||||
case RTM_NEWADDR:
|
||||
|
||||
lwsl_cx_netlink(cx, "NEWADDR");
|
||||
ana:
|
||||
|
||||
/*
|
||||
* Is robj a dupe in the routing table already?
|
||||
*
|
||||
* match on pri ignore == set pri and skip
|
||||
* no match == add
|
||||
*
|
||||
* returns zero ALWAYS
|
||||
*
|
||||
* We could be adding a route to the same destination with
|
||||
* a higher or lower priority from a different source, so why
|
||||
* all existing routes? Only remove if its the same source and
|
||||
* destination, effectively a change in priority.
|
||||
*/
|
||||
_lws_route_remove(pt, &robj,
|
||||
LRR_MATCH_DST | LRR_MATCH_SRC | LRR_IGNORE_PRI);
|
||||
|
||||
lws_pt_lock(pt, __func__);
|
||||
|
||||
/* returns zero on match already in table */
|
||||
rmat = _lws_route_remove(pt, &robj, h->nlmsg_type == RTM_NEWROUTE ?
|
||||
LRR_MATCH_DST : LRR_MATCH_SRC | LRR_IGNORE_PRI);
|
||||
lws_pt_unlock(pt);
|
||||
|
||||
if (rmat) {
|
||||
rmat->priority = robj.priority;
|
||||
break;
|
||||
}
|
||||
|
||||
rou = lws_malloc(sizeof(*rou), __func__);
|
||||
if (!rou) {
|
||||
lwsl_cx_err(cx, "oom");
|
||||
return LWS_HPI_RET_HANDLED;
|
||||
}
|
||||
|
||||
*rou = robj;
|
||||
|
||||
lws_pt_lock(pt, __func__);
|
||||
|
||||
/*
|
||||
* We lock the pt before getting the uidx, so it
|
||||
* cannot race
|
||||
*/
|
||||
|
||||
/* add route to linked-list */
|
||||
rou->uidx = _lws_route_get_uidx(cx);
|
||||
lws_dll2_add_tail(&rou->list, &cx->routing_table);
|
||||
lwsl_cx_info(cx, "route list size %u",
|
||||
cx->routing_table.count);
|
||||
|
||||
_lws_route_pt_close_unroutable(pt);
|
||||
|
||||
lws_pt_unlock(pt);
|
||||
|
||||
lwsl_cx_netlink_debug(cx, "route list size %u",
|
||||
cx->routing_table.count);
|
||||
|
||||
/*
|
||||
* 3. Close anyything we cant reach anymore due to the removal.
|
||||
* (don't need to or want to do this under lock)
|
||||
*/
|
||||
_lws_route_pt_close_unroutable(pt);
|
||||
|
||||
inform:
|
||||
#if defined(_DEBUG)
|
||||
route_change = 1;
|
||||
|
@ -416,12 +465,39 @@ inform:
|
|||
*/
|
||||
(void)lws_smd_msg_printf(cx, LWSSMDCL_NETWORK,
|
||||
"{\"rt\":\"%s\"}\n",
|
||||
(h->nlmsg_type == RTM_DELROUTE) ?
|
||||
"del" : "add");
|
||||
(h->nlmsg_type == RTM_NEWROUTE) ?
|
||||
"add" : "del");
|
||||
#endif
|
||||
|
||||
break;
|
||||
|
||||
case RTM_DELADDR:
|
||||
lwsl_cx_notice(cx, "DELADDR");
|
||||
#if defined(_DEBUG)
|
||||
_lws_routing_entry_dump(cx, &robj);
|
||||
#endif
|
||||
lws_pt_lock(pt, __func__);
|
||||
removed = cx->routing_table.count;
|
||||
_lws_route_remove(pt, &robj, LRR_MATCH_SRC | LRR_IGNORE_PRI);
|
||||
removed -= cx->routing_table.count;
|
||||
lws_pt_unlock(pt);
|
||||
_lws_route_pt_close_unroutable(pt);
|
||||
if (removed > 0)
|
||||
goto inform;
|
||||
break;
|
||||
|
||||
case RTM_NEWADDR:
|
||||
lwsl_cx_netlink(cx, "NEWADDR (nothing to do)");
|
||||
#if defined(_DEBUG)
|
||||
_lws_routing_entry_dump(cx, &robj);
|
||||
#endif
|
||||
/*
|
||||
* An address alone does not provide new routes.
|
||||
* NEWADDR will happen when the DHCP lease is being
|
||||
* renewed, and will likely not change any routes.
|
||||
*/
|
||||
break;
|
||||
|
||||
default:
|
||||
// lwsl_info("%s: unknown msg type %d\n", __func__,
|
||||
// h->nlmsg_type);
|
||||
|
|
|
@ -637,6 +637,7 @@ utf8_fail:
|
|||
|
||||
if (n == PMDR_DID_NOTHING
|
||||
#if !defined(LWS_WITHOUT_EXTENSIONS)
|
||||
|| n == PMDR_NOTHING_WE_SHOULD_DO
|
||||
|| n == PMDR_UNKNOWN
|
||||
#endif
|
||||
)
|
||||
|
|
|
@ -257,15 +257,15 @@ lws_client_ws_upgrade(struct lws *wsi, const char **cce)
|
|||
}
|
||||
|
||||
if (wsi->http.ah->http_response == 401) {
|
||||
lwsl_wsi_warn(wsi, "got bad HTTP response '%d'",
|
||||
wsi->http.ah->http_response);
|
||||
lwsl_wsi_warn(wsi, "got bad HTTP response '%ld'",
|
||||
(long)wsi->http.ah->http_response);
|
||||
*cce = "HS: ws upgrade unauthorized";
|
||||
goto bail3;
|
||||
}
|
||||
|
||||
if (wsi->http.ah->http_response != 101) {
|
||||
lwsl_wsi_warn(wsi, "got bad HTTP response '%d'",
|
||||
wsi->http.ah->http_response);
|
||||
lwsl_wsi_warn(wsi, "got bad HTTP response '%ld'",
|
||||
(long)wsi->http.ah->http_response);
|
||||
*cce = "HS: ws upgrade response not 101";
|
||||
goto bail3;
|
||||
}
|
||||
|
|
|
@ -248,12 +248,13 @@ lws_apply_metadata(lws_ss_handle_t *h, struct lws *wsi, uint8_t *buf,
|
|||
}
|
||||
|
||||
/*
|
||||
* Content-length on POST / PUT if we have the length information
|
||||
* Content-length on POST / PUT / PATCH if we have the length information
|
||||
*/
|
||||
|
||||
if (h->policy->u.http.method && (
|
||||
(!strcmp(h->policy->u.http.method, "POST") ||
|
||||
!strcmp(h->policy->u.http.method, "PUT"))) &&
|
||||
!strcmp(h->policy->u.http.method, "PATCH") ||
|
||||
!strcmp(h->policy->u.http.method, "PUT"))) &&
|
||||
wsi->http.writeable_len) {
|
||||
if (!(h->policy->flags &
|
||||
LWSSSPOLF_HTTP_NO_CONTENT_LENGTH)) {
|
||||
|
@ -840,6 +841,7 @@ malformed:
|
|||
h->policy->protocol == LWSSSP_H2) &&
|
||||
h->being_serialized && (
|
||||
!strcmp(h->policy->u.http.method, "PUT") ||
|
||||
!strcmp(h->policy->u.http.method, "PATCH") ||
|
||||
!strcmp(h->policy->u.http.method, "POST"))) {
|
||||
|
||||
wsi->client_suppress_CONNECTION_ERROR = 1;
|
||||
|
@ -1105,6 +1107,16 @@ malformed:
|
|||
return -1;
|
||||
if (lws_ss_alloc_set_metadata(h, "method", "POST", 4))
|
||||
return -1;
|
||||
} else {
|
||||
m = lws_hdr_total_length(wsi, WSI_TOKEN_PATCH_URI);
|
||||
if (m) {
|
||||
if (lws_ss_alloc_set_metadata(h, "path",
|
||||
lws_hdr_simple_ptr(wsi,
|
||||
WSI_TOKEN_PATCH_URI), (unsigned int)m))
|
||||
return -1;
|
||||
if (lws_ss_alloc_set_metadata(h, "method", "PATCH", 5))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -464,7 +464,7 @@ lws_ss_sigv4_set_aws_key(struct lws_context* context, uint8_t idx,
|
|||
|
||||
#if defined(__linux__) || defined(__APPLE__) || defined(WIN32) || \
|
||||
defined(__FreeBSD__) || defined(__NetBSD__) || defined(__ANDROID__) || \
|
||||
defined(__sun) || defined(__OpenBSD__)
|
||||
defined(__sun) || defined(__OpenBSD__) || defined(__NuttX__)
|
||||
|
||||
/* ie, if we have filesystem ops */
|
||||
|
||||
|
|
|
@ -401,7 +401,8 @@ if (LWS_WITH_MBEDTLS)
|
|||
else()
|
||||
CHECK_C_SOURCE_COMPILES("#include <mbedtls/x509_crt.h>\nint main(void) { struct mbedtls_x509_crt c; c.authority_key_id.keyIdentifier.tag = MBEDTLS_ASN1_OCTET_STRING; return c.authority_key_id.keyIdentifier.tag; }\n" LWS_HAVE_MBEDTLS_AUTH_KEY_ID)
|
||||
CHECK_C_SOURCE_COMPILES("#include <mbedtls/ssl.h>\nint main(void) { void *v = (void *)mbedtls_ssl_set_verify; return !!v; }\n" LWS_HAVE_mbedtls_ssl_set_verify)
|
||||
CHECK_SYMBOL_EXISTS(mbedtls_ssl_conf_alpn_protocols LWS_HAVE_mbedtls_ssl_conf_alpn_protocols PARENT_SCOPE)
|
||||
CHECK_C_SOURCE_COMPILES("#include <mbedtls/ssl.h>\nint main(void) { void *v = (void *)mbedtls_ssl_conf_alpn_protocols; return !!v; }\n" LWS_HAVE_mbedtls_ssl_conf_alpn_protocols)
|
||||
|
||||
CHECK_FUNCTION_EXISTS(mbedtls_ssl_get_alpn_protocol LWS_HAVE_mbedtls_ssl_get_alpn_protocol PARENT_SCOPE)
|
||||
CHECK_FUNCTION_EXISTS(mbedtls_ssl_conf_sni LWS_HAVE_mbedtls_ssl_conf_sni PARENT_SCOPE)
|
||||
CHECK_FUNCTION_EXISTS(mbedtls_ssl_set_hs_ca_chain LWS_HAVE_mbedtls_ssl_set_hs_ca_chain PARENT_SCOPE)
|
||||
|
@ -570,6 +571,8 @@ endif()
|
|||
|
||||
exports_to_parent_scope()
|
||||
set(LWS_HAVE_MBEDTLS_NET_SOCKETS ${LWS_HAVE_MBEDTLS_NET_SOCKETS} PARENT_SCOPE)
|
||||
set(LWS_HAVE_MBEDTLS_SSL_NEW_SESSION_TICKET ${LWS_HAVE_MBEDTLS_SSL_NEW_SESSION_TICKET} PARENT_SCOPE)
|
||||
set(LWS_HAVE_mbedtls_ssl_conf_alpn_protocols ${LWS_HAVE_mbedtls_ssl_conf_alpn_protocols} PARENT_SCOPE)
|
||||
set(TEST_SERVER_SSL_KEY "${TEST_SERVER_SSL_KEY}" PARENT_SCOPE)
|
||||
set(TEST_SERVER_SSL_CERT "${TEST_SERVER_SSL_CERT}" PARENT_SCOPE)
|
||||
set(TEST_SERVER_DATA ${TEST_SERVER_DATA} PARENT_SCOPE)
|
||||
|
|
|
@ -124,6 +124,7 @@ include_directories(wrapper/include wrapper/include/internal)
|
|||
# old mbedtls has everything in mbedtls/net.h
|
||||
|
||||
CHECK_C_SOURCE_COMPILES("#include <mbedtls/net_sockets.h>\nint main(void) { return 0;}\n" LWS_HAVE_MBEDTLS_NET_SOCKETS)
|
||||
CHECK_C_SOURCE_COMPILES("#include <mbedtls/ssl.h>\nint main(void) { return MBEDTLS_SSL_NEW_SESSION_TICKET;}\n" LWS_HAVE_MBEDTLS_SSL_NEW_SESSION_TICKET)
|
||||
|
||||
#
|
||||
# Keep explicit parent scope exports at end
|
||||
|
@ -131,3 +132,4 @@ CHECK_C_SOURCE_COMPILES("#include <mbedtls/net_sockets.h>\nint main(void) { retu
|
|||
|
||||
exports_to_parent_scope()
|
||||
set(LWS_HAVE_MBEDTLS_NET_SOCKETS ${LWS_HAVE_MBEDTLS_NET_SOCKETS} PARENT_SCOPE)
|
||||
set(LWS_HAVE_MBEDTLS_SSL_NEW_SESSION_TICKET ${LWS_HAVE_MBEDTLS_SSL_NEW_SESSION_TICKET} PARENT_SCOPE)
|
||||
|
|
|
@ -183,7 +183,12 @@ int ssl_pm_new(SSL *ssl)
|
|||
mbedtls_ssl_conf_min_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, version);
|
||||
} else {
|
||||
mbedtls_ssl_conf_max_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3);
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
mbedtls_ssl_conf_min_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3);
|
||||
#else
|
||||
mbedtls_ssl_conf_min_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_rng(&ssl_pm->conf, mbedtls_ctr_drbg_random, &ssl_pm->ctr_drbg);
|
||||
|
@ -251,9 +256,9 @@ static int ssl_pm_reload_crt(SSL *ssl)
|
|||
struct x509_pm *crt_pm = (struct x509_pm *)ssl->cert->x509->x509_pm;
|
||||
|
||||
if (ssl->verify_mode == SSL_VERIFY_PEER)
|
||||
mode = MBEDTLS_SSL_VERIFY_REQUIRED;
|
||||
else if (ssl->verify_mode == SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
|
||||
mode = MBEDTLS_SSL_VERIFY_OPTIONAL;
|
||||
else if (ssl->verify_mode == SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
|
||||
mode = MBEDTLS_SSL_VERIFY_REQUIRED;
|
||||
else if (ssl->verify_mode == SSL_VERIFY_CLIENT_ONCE)
|
||||
mode = MBEDTLS_SSL_VERIFY_UNSET;
|
||||
else
|
||||
|
@ -549,7 +554,11 @@ OSSL_HANDSHAKE_STATE ssl_pm_get_state(const SSL *ssl)
|
|||
case MBEDTLS_SSL_SERVER_KEY_EXCHANGE:
|
||||
state = TLS_ST_SR_KEY_EXCH;
|
||||
break;
|
||||
#if defined(LWS_HAVE_MBEDTLS_SSL_NEW_SESSION_TICKET)
|
||||
case MBEDTLS_SSL_NEW_SESSION_TICKET:
|
||||
#else
|
||||
case MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET:
|
||||
#endif
|
||||
state = TLS_ST_SW_SESSION_TICKET;
|
||||
break;
|
||||
case MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT:
|
||||
|
@ -761,8 +770,13 @@ int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len)
|
|||
mbedtls_pk_init(pkey_pm->pkey);
|
||||
|
||||
#if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||
#if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03050000
|
||||
ret = mbedtls_pk_parse_key(pkey_pm->pkey, load_buf, (unsigned int)len, NULL, 0,
|
||||
mbedtls_ctr_drbg_random, pkey_pm->rngctx);
|
||||
#else
|
||||
ret = mbedtls_pk_parse_key(pkey_pm->pkey, load_buf, (unsigned int)len + 1, NULL, 0,
|
||||
mbedtls_ctr_drbg_random, pkey_pm->rngctx);
|
||||
#endif
|
||||
#else
|
||||
ret = mbedtls_pk_parse_key(pkey_pm->pkey, load_buf, (unsigned int)len + 1, NULL, 0);
|
||||
#endif
|
||||
|
|
|
@ -517,6 +517,7 @@ lws_tls_client_connect(struct lws *wsi, char *errbuf, size_t elen)
|
|||
unsigned int len;
|
||||
#endif
|
||||
int m, n, en;
|
||||
unsigned long l;
|
||||
#if defined(LWS_WITH_TLS_SESSIONS) && defined(LWS_HAVE_SSL_SESSION_set_time)
|
||||
SSL_SESSION *sess;
|
||||
#endif
|
||||
|
@ -541,9 +542,10 @@ lws_tls_client_connect(struct lws *wsi, char *errbuf, size_t elen)
|
|||
}
|
||||
|
||||
if (m == SSL_ERROR_SSL) {
|
||||
l = ERR_get_error();
|
||||
n = lws_snprintf(errbuf, elen, "tls: %s", wsi->tls.err_helper);
|
||||
if (!wsi->tls.err_helper[0])
|
||||
ERR_error_string_n((unsigned int)m, errbuf + n, (elen - (unsigned int)n));
|
||||
ERR_error_string_n((unsigned int)l, errbuf + n, (elen - (unsigned int)n));
|
||||
return LWS_SSL_CAPABLE_ERROR;
|
||||
}
|
||||
|
||||
|
@ -922,6 +924,10 @@ lws_tls_client_create_vhost_context(struct lws_vhost *vh,
|
|||
return 1;
|
||||
}
|
||||
|
||||
SSL_CTX_set_ex_data(vh->tls.ssl_client_ctx,
|
||||
openssl_SSL_CTX_private_data_index,
|
||||
(char *)vh->context);
|
||||
|
||||
lws_plat_vhost_tls_client_ctx_init(vh);
|
||||
|
||||
tcr = lws_zalloc(sizeof(*tcr), "client ctx tcr");
|
||||
|
|
|
@ -706,7 +706,7 @@ lws_tls_server_abort_connection(struct lws *wsi)
|
|||
SSL_shutdown(wsi->tls.ssl);
|
||||
SSL_free(wsi->tls.ssl);
|
||||
|
||||
return 0;
|
||||
return LWS_SSL_CAPABLE_DONE;
|
||||
}
|
||||
|
||||
enum lws_ssl_capable_status
|
||||
|
|
|
@ -57,8 +57,6 @@ int lws_ssl_get_error(struct lws *wsi, int n)
|
|||
|
||||
m = SSL_get_error(wsi->tls.ssl, n);
|
||||
lwsl_debug("%s: %p %d -> %d (errno %d)\n", __func__, wsi->tls.ssl, n, m, LWS_ERRNO);
|
||||
if (m == SSL_ERROR_SSL)
|
||||
lws_tls_err_describe_clear();
|
||||
|
||||
// assert (LWS_ERRNO != 9);
|
||||
|
||||
|
@ -250,6 +248,9 @@ lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, size_t len)
|
|||
if (m == SSL_ERROR_ZERO_RETURN) /* cleanly shut down */
|
||||
goto do_err;
|
||||
|
||||
if (m == SSL_ERROR_SSL)
|
||||
lws_tls_err_describe_clear();
|
||||
|
||||
/* hm not retryable.. could be 0 size pkt or error */
|
||||
|
||||
if (m == SSL_ERROR_SSL || m == SSL_ERROR_SYSCALL ||
|
||||
|
|
|
@ -69,7 +69,7 @@ static const struct ipparser_tests {
|
|||
|
||||
#define TEST_FLAG_NOCHECK_RESULT_IP 0x100000
|
||||
|
||||
static const struct async_dns_tests {
|
||||
static struct async_dns_tests {
|
||||
const char *dns_name;
|
||||
int recordtype;
|
||||
int addrlen;
|
||||
|
@ -390,13 +390,52 @@ void sigint_handler(int sig)
|
|||
interrupted = 1;
|
||||
}
|
||||
|
||||
int
|
||||
fixup(int idx)
|
||||
{
|
||||
struct addrinfo hints, *ai;
|
||||
int m;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
|
||||
m = getaddrinfo(adt[idx].dns_name, "80", &hints, &ai);
|
||||
if (m) {
|
||||
lwsl_err("Unable to look up %s: %s", adt[0].dns_name,
|
||||
gai_strerror(m));
|
||||
return 1;
|
||||
}
|
||||
adt[idx].ads[0] = (uint8_t)((struct sockaddr *)ai->ai_addr)->sa_data[2];
|
||||
adt[idx].ads[1] = (uint8_t)((struct sockaddr *)ai->ai_addr)->sa_data[3];
|
||||
adt[idx].ads[2] = (uint8_t)((struct sockaddr *)ai->ai_addr)->sa_data[4];
|
||||
adt[idx].ads[3] = (uint8_t)((struct sockaddr *)ai->ai_addr)->sa_data[5];
|
||||
|
||||
freeaddrinfo(ai);
|
||||
|
||||
lwsl_notice("%s: %u.%u.%u.%u\n", __func__,
|
||||
adt[idx].ads[0], adt[idx].ads[1], adt[idx].ads[2], adt[idx].ads[3]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, const char **argv)
|
||||
{
|
||||
int n = 1, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE;
|
||||
struct lws_context_creation_info info;
|
||||
uint8_t mac[6];
|
||||
const char *p;
|
||||
|
||||
/* fixup dynamic target addresses we're testing against */
|
||||
|
||||
fixup(0);
|
||||
fixup(1);
|
||||
fixup(2);
|
||||
fixup(5);
|
||||
fixup(6);
|
||||
|
||||
/* the normal lws init */
|
||||
|
||||
signal(SIGINT, sigint_handler);
|
||||
|
@ -479,6 +518,40 @@ main(int argc, const char **argv)
|
|||
ok++;
|
||||
}
|
||||
|
||||
/* mac address parser tests */
|
||||
|
||||
if (lws_parse_mac("11:ff:ce:CE:22:33", mac)) {
|
||||
lwsl_err("%s: mac fail 1\n", __func__);
|
||||
lwsl_hexdump_notice(mac, 6);
|
||||
fail++;
|
||||
} else
|
||||
if (mac[0] != 0x11 || mac[1] != 0xff || mac[2] != 0xce ||
|
||||
mac[3] != 0xce || mac[4] != 0x22 || mac[5] != 0x33) {
|
||||
lwsl_err("%s: mac fail 2\n", __func__);
|
||||
lwsl_hexdump_notice(mac, 6);
|
||||
fail++;
|
||||
}
|
||||
if (!lws_parse_mac("11:ff:ce:CE:22:3", mac)) {
|
||||
lwsl_err("%s: mac fail 3\n", __func__);
|
||||
lwsl_hexdump_notice(mac, 6);
|
||||
fail++;
|
||||
}
|
||||
if (!lws_parse_mac("11:ff:ce:CE:22", mac)) {
|
||||
lwsl_err("%s: mac fail 4\n", __func__);
|
||||
lwsl_hexdump_notice(mac, 6);
|
||||
fail++;
|
||||
}
|
||||
if (!lws_parse_mac("11:ff:ce:CE:22:", mac)) {
|
||||
lwsl_err("%s: mac fail 5\n", __func__);
|
||||
lwsl_hexdump_notice(mac, 6);
|
||||
fail++;
|
||||
}
|
||||
if (!lws_parse_mac("11:ff:ce:CE22", mac)) {
|
||||
lwsl_err("%s: mac fail 6\n", __func__);
|
||||
lwsl_hexdump_notice(mac, 6);
|
||||
fail++;
|
||||
}
|
||||
|
||||
#if !defined(LWS_WITH_IPV6)
|
||||
_exp -= 2;
|
||||
#endif
|
||||
|
|
23
minimal-examples-lowlevel/raw/minimal-raw-wol/CMakeLists.txt
Normal file
23
minimal-examples-lowlevel/raw/minimal-raw-wol/CMakeLists.txt
Normal file
|
@ -0,0 +1,23 @@
|
|||
project(lws-minimal-raw-wol C)
|
||||
cmake_minimum_required(VERSION 3.6)
|
||||
find_package(libwebsockets CONFIG REQUIRED)
|
||||
list(APPEND CMAKE_MODULE_PATH ${LWS_CMAKE_DIR})
|
||||
include(CheckCSourceCompiles)
|
||||
include(LwsCheckRequirements)
|
||||
|
||||
set(SAMP lws-minimal-raw-wol)
|
||||
set(SRCS minimal-raw-wol.c)
|
||||
|
||||
set(requirements 1)
|
||||
require_lws_config(LWS_WITH_WOL 1 requirements)
|
||||
|
||||
if (requirements)
|
||||
add_executable(${SAMP} ${SRCS})
|
||||
|
||||
if (websockets_shared)
|
||||
target_link_libraries(${SAMP} websockets_shared ${LIBWEBSOCKETS_DEP_LIBS})
|
||||
add_dependencies(${SAMP} websockets_shared)
|
||||
else()
|
||||
target_link_libraries(${SAMP} websockets ${LIBWEBSOCKETS_DEP_LIBS})
|
||||
endif()
|
||||
endif()
|
34
minimal-examples-lowlevel/raw/minimal-raw-wol/README.md
Normal file
34
minimal-examples-lowlevel/raw/minimal-raw-wol/README.md
Normal file
|
@ -0,0 +1,34 @@
|
|||
# lws minimal raw wol
|
||||
|
||||
This example shows how to send a Wake On Lan magic packet to a given mac.
|
||||
|
||||
## build
|
||||
|
||||
```
|
||||
$ cmake . && make
|
||||
```
|
||||
|
||||
## usage
|
||||
|
||||
```
|
||||
$ bin/lws-minimal-raw-wol b4:2e:99:a9:22:90
|
||||
[2023/11/09 12:25:24:2255] N: lws_create_context: LWS: 4.3.99-v4.3.0-295-g60d671c7, NET CLI SRV H1 H2 WS SS-JSON-POL ConMon ASYNC_DNS IPv6-absent
|
||||
[2023/11/09 12:25:24:2256] N: __lws_lc_tag: ++ [wsi|0|pipe] (1)
|
||||
[2023/11/09 12:25:24:2256] N: __lws_lc_tag: ++ [vh|0|netlink] (1)
|
||||
[2023/11/09 12:25:24:2256] N: __lws_lc_tag: ++ [vh|1|system||-1] (2)
|
||||
[2023/11/09 12:25:24:2257] N: __lws_lc_tag: ++ [wsisrv|0|system|asyncdns] (1)
|
||||
[2023/11/09 12:25:24:2257] N: __lws_lc_tag: ++ [wsisrv|1|system|asyncdns] (2)
|
||||
[2023/11/09 12:25:24:2257] N: __lws_lc_tag: ++ [vh|2|default||0] (3)
|
||||
[2023/11/09 12:25:24:2257] N: [vh|2|default||0]: lws_socket_bind: source ads 0.0.0.0
|
||||
[2023/11/09 12:25:24:2257] N: __lws_lc_tag: ++ [wsi|1|listen|default||33749] (2)
|
||||
[2023/11/09 12:25:24:2257] N: lws_wol: Sending WOL to B4:2E:99:A9:22:90
|
||||
[2023/11/09 12:25:24:2258] N: __lws_lc_untag: -- [wsi|0|pipe] (1) 190μs
|
||||
[2023/11/09 12:25:24:2258] N: __lws_lc_untag: -- [wsi|1|listen|default||33749] (0) 80μs
|
||||
[2023/11/09 12:25:24:2258] N: __lws_lc_untag: -- [wsisrv|1|system|asyncdns] (1) 118μs
|
||||
[2023/11/09 12:25:24:2258] N: __lws_lc_untag: -- [wsisrv|0|system|asyncdns] (0) 155μs
|
||||
[2023/11/09 12:25:24:2258] N: __lws_lc_untag: -- [vh|0|netlink] (2) 198μs
|
||||
[2023/11/09 12:25:24:2258] N: __lws_lc_untag: -- [vh|1|system||-1] (1) 182μs
|
||||
[2023/11/09 12:25:24:2258] N: __lws_lc_untag: -- [vh|2|default||0] (0) 125μs
|
||||
|
||||
$
|
||||
```
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* lws-minimal-raw-wol
|
||||
*
|
||||
* Written in 2010-2023 by Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This file is made available under the Creative Commons CC0 1.0
|
||||
* Universal Public Domain Dedication.
|
||||
*
|
||||
* This demonstrates using lws_wol()
|
||||
*/
|
||||
|
||||
#include <libwebsockets.h>
|
||||
#include <net/if.h>
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
struct lws_context_creation_info info;
|
||||
struct lws_context *ctx;
|
||||
const char *p, *ip = NULL;
|
||||
uint8_t mac[IFHWADDRLEN];
|
||||
int ret = 1;
|
||||
|
||||
memset(&info, 0, sizeof info);
|
||||
lws_cmdline_option_handle_builtin(argc, argv, &info);
|
||||
|
||||
if ((p = lws_cmdline_option(argc, argv, "-ip")))
|
||||
ip = p;
|
||||
|
||||
if (argc < 2) {
|
||||
lwsl_user("lws-minimal-raw-wol XX:XX:XX:XX:XX:XX [-ip interface IP]\n");
|
||||
goto bail1;
|
||||
}
|
||||
|
||||
if (lws_parse_mac(argv[1], mac)) {
|
||||
lwsl_user("Failed to parse mac '%s'\n", argv[1]);
|
||||
goto bail1;
|
||||
}
|
||||
|
||||
ctx = lws_create_context(&info);
|
||||
if (!ctx) {
|
||||
lwsl_err("lws init failed\n");
|
||||
goto bail1;
|
||||
}
|
||||
|
||||
if (!lws_wol(ctx, ip, mac))
|
||||
ret = 0;
|
||||
|
||||
lws_context_destroy(ctx);
|
||||
|
||||
bail1:
|
||||
return ret;
|
||||
}
|
Loading…
Add table
Reference in a new issue