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

mbed3 workable plus or minus mbed3 net stack bug

https://github.com/ARMmbed/sockets/issues/35

Signed-off-by: Andy Green <andy.green@linaro.org>
This commit is contained in:
Andy Green 2015-11-08 12:10:26 +08:00
parent 8c0d3c035c
commit 11f27345d2
11 changed files with 231 additions and 99 deletions

View file

@ -558,9 +558,9 @@ lws_client_interpret_server_handshake(struct libwebsocket_context *context,
}
pc = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS);
if (pc == NULL)
if (pc == NULL) {
lwsl_parser("lws_client_int_s_hs: no protocol list\n");
else
} else
lwsl_parser("lws_client_int_s_hs: protocol list '%s'\n", pc);
/*

View file

@ -99,9 +99,10 @@ libwebsocket_create_context(struct lws_context_creation_info *info)
lwsl_info(" SPEC_LATEST_SUPPORTED: %u\n", SPEC_LATEST_SUPPORTED);
lwsl_info(" AWAITING_TIMEOUT: %u\n", AWAITING_TIMEOUT);
#if LWS_POSIX
lwsl_info(" SYSTEM_RANDOM_FILEPATH: '%s'\n", SYSTEM_RANDOM_FILEPATH);
lwsl_info(" LWS_MAX_ZLIB_CONN_BUFFER: %u\n", LWS_MAX_ZLIB_CONN_BUFFER);
#endif
if (lws_plat_context_early_init())
return NULL;
@ -116,7 +117,6 @@ libwebsocket_create_context(struct lws_context_creation_info *info)
lwsl_notice(" Started with daemon pid %d\n", pid_daemon);
}
#endif
lwsl_notice(" context: %p\r\n", context);
context->listen_service_extraseen = 0;
context->protocols = info->protocols;
@ -146,7 +146,6 @@ libwebsocket_create_context(struct lws_context_creation_info *info)
context->lws_ev_sigint_cb = &libwebsocket_sigint_cb;
#endif /* LWS_USE_LIBEV */
#if LWS_POSIX
/* to reduce this allocation, */
context->max_fds = getdtablesize();
lwsl_notice(" static allocation: %u + (%u x %u fds) = %u bytes\n",
@ -174,7 +173,7 @@ libwebsocket_create_context(struct lws_context_creation_info *info)
if (lws_plat_init_fd_tables(context)) {
goto bail;
}
#endif
lws_context_init_extensions(info, context);
context->user_space = info->user;
@ -225,8 +224,8 @@ libwebsocket_create_context(struct lws_context_creation_info *info)
info->protocols[context->count_protocols].callback;
context->count_protocols++) {
lwsl_notice(" Protocol: %s\n",
info->protocols[context->count_protocols].name);
// lwsl_notice(" Protocol: %s\n",
// info->protocols[context->count_protocols].name);
info->protocols[context->count_protocols].owning_server =
context;

View file

@ -310,8 +310,10 @@ just_kill_connection:
if (n)
lwsl_debug("closing: close ret %d\n", LWS_ERRNO);
wsi->sock = LWS_SOCK_INVALID;
#else
compatible_close(wsi->sock);
#endif
wsi->sock = LWS_SOCK_INVALID;
}
/* outermost destroy notification for wsi (user_space still intact) */
@ -709,7 +711,7 @@ libwebsocket_set_proxy(struct libwebsocket_context *context, const char *proxy)
p = strchr(proxy, '@');
if (p) { /* auth is around */
if ((p - proxy) > sizeof(authstring) - 1)
if ((unsigned int)(p - proxy) > sizeof(authstring) - 1)
goto auth_too_long;
strncpy(authstring + 6, proxy, p - proxy);

View file

@ -49,8 +49,15 @@ class lws_conn {
public:
void set_wsi(struct libwebsocket *_wsi) { wsi = _wsi; }
int actual_onRX(Socket *s);
void onRX(Socket *s);
void onError(Socket *s, socket_error_t err);
void onDisconnect(TCPStream *s);
void onSent(Socket *s, uint16_t len);
public:
TCPStream *ts;
Socket *s_HACK;
public:
struct libwebsocket *wsi;
@ -72,16 +79,11 @@ protected:
void onError(Socket *s, socket_error_t err);
void onIncoming(TCPListener *s, void *impl);
void onDisconnect(TCPStream *s);
void onSent(Socket *s, uint16_t len);
public:
TCPListener srv;
};
#define LWS_POSIX 0
#else
#define LWS_POSIX 1
#endif
extern "C" {
@ -89,6 +91,12 @@ extern "C" {
#include <stdarg.h>
#endif
#ifdef MBED_OPERATORS
#define LWS_POSIX 0
#else
#define LWS_POSIX 1
#endif
#include "lws_config.h"
#if defined(WIN32) || defined(_WIN32)
@ -311,6 +319,7 @@ WINSOCK_API_LINKAGE int WSAAPI WSAPoll(struct libwebsocket_pollfd fdArray[], ULO
#else
#if defined(MBED_OPERATORS)
/* it's a class lws_conn * */
typedef void * lws_sockfd_type;
#define lws_sockfd_valid(sfd) (!!sfd)
struct pollfd {
@ -332,7 +341,7 @@ void mbed3_delete_tcp_stream_socket(void *sockfd);
void mbed3_tcp_stream_bind(void *sock, int port, struct libwebsocket *);
void mbed3_tcp_stream_accept(void *sock, struct libwebsocket *);
#else
typedef int lws_fd_type;
typedef int lws_sockfd_type;
#define lws_sockfd_valid(sfd) (sfd >= 0)
#endif

View file

@ -1,25 +1,31 @@
#include "private-libwebsockets.h"
#include "core-util/CriticalSectionLock.h"
extern "C" void *mbed3_create_tcp_stream_socket(void)
{
lws_conn_listener *srv = new lws_conn_listener;
printf("%s: %p\r\n", __func__, (void *)srv);
//lwsl_notice("%s: %p\r\n", __func__, (void *)srv);
return (void *)srv;
}
/* this is called by compatible_close() */
extern "C" void mbed3_delete_tcp_stream_socket(void *sock)
{
printf("%s: %p\r\n", __func__, sock);
delete (lws_conn *)sock;
lws_conn *conn = (lws_conn *)sock;
conn->ts->close();
lwsl_notice("%s: wsi %p: conn %p\r\n", __func__, (void *)conn->wsi, sock);
delete conn;
}
extern "C" void mbed3_tcp_stream_bind(void *sock, int port, struct libwebsocket *wsi)
{
lws_conn_listener *srv = (lws_conn_listener *)sock;
lwsl_notice("%s\r\n", __func__);
lwsl_info("%s\r\n", __func__);
/* associate us with the listening wsi */
((lws_conn *)srv)->set_wsi(wsi);
@ -31,10 +37,69 @@ extern "C" void mbed3_tcp_stream_accept(void *sock, struct libwebsocket *wsi)
{
lws_conn *conn = (lws_conn *)sock;
lwsl_notice("%s\r\n", __func__);
lwsl_info("%s\r\n", __func__);
conn->set_wsi(wsi);
}
extern "C" LWS_VISIBLE int
lws_ssl_capable_read_no_ssl(struct libwebsocket_context *context,
struct libwebsocket *wsi, unsigned char *buf, int len)
{
socket_error_t err;
size_t _len = len;
lwsl_debug("%s\r\n", __func__);
(void)context;
/* s/s_HACK/ts/g when mbed3 listen payload bug fixed */
err = ((lws_conn *)wsi->sock)->s_HACK->recv((char *)buf, &_len);
if (err == SOCKET_ERROR_NONE) {
lwsl_info("%s: got %d bytes\n", __func__, _len);
return _len;
}
#if LWS_POSIX
if (LWS_ERRNO == LWS_EAGAIN ||
LWS_ERRNO == LWS_EWOULDBLOCK ||
LWS_ERRNO == LWS_EINTR)
#else
if (err == SOCKET_ERROR_WOULD_BLOCK)
#endif
return LWS_SSL_CAPABLE_MORE_SERVICE;
// !!! while listen payload mbed3 bug, don't error out if nothing */
// if (((lws_conn *)wsi->sock)->s_HACK != ((Socket *)((lws_conn *)wsi->sock)->ts))
// return 0;
lwsl_warn("error on reading from skt: %d\n", err);
return LWS_SSL_CAPABLE_ERROR;
}
extern "C" LWS_VISIBLE int
lws_ssl_capable_write_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len)
{
socket_error_t err;
lwsl_debug("%s: wsi %p: write %d (from %p)\n", __func__, (void *)wsi, len, (void *)buf);
err = ((lws_conn *)wsi->sock)->ts->send((char *)buf, len);
if (err == SOCKET_ERROR_NONE)
return len;
#if LWS_POSIX
if (LWS_ERRNO == LWS_EAGAIN ||
LWS_ERRNO == LWS_EWOULDBLOCK ||
LWS_ERRNO == LWS_EINTR) {
if (LWS_ERRNO == LWS_EWOULDBLOCK)
lws_set_blocking_send(wsi);
#else
if (err == SOCKET_ERROR_WOULD_BLOCK)
return LWS_SSL_CAPABLE_MORE_SERVICE;
#endif
lwsl_warn("%s: wsi %p: ERROR %d writing len %d to skt\n", __func__, (void *)wsi, err, len);
return LWS_SSL_CAPABLE_ERROR;
}
/*
* Set the listening socket to listen.
*/
@ -53,6 +118,21 @@ void lws_conn_listener::start(const uint16_t port)
srv.error_check(err);
}
int lws_conn::actual_onRX(Socket *s)
{
struct libwebsocket_pollfd pollfd;
pollfd.fd = this;
pollfd.events = POLLIN;
pollfd.revents = POLLIN;
lwsl_debug("%s: lws %p\n", __func__, wsi);
s_HACK = s;
return libwebsocket_service_fd(wsi->protocol->owning_server, &pollfd);
}
/*
* this gets called from the OS when the TCPListener gets a connection that
* needs accept()-ing. LWS needs to run the associated flow.
@ -60,78 +140,100 @@ void lws_conn_listener::start(const uint16_t port)
void lws_conn_listener::onIncoming(TCPListener *tl, void *impl)
{
mbed::util::CriticalSectionLock lock;
TCPStream *ts = srv.accept(impl);
lws_conn *conn;
printf("%s\r\n", __func__);
if (!impl) {
if (!impl || !ts) {
onError(tl, SOCKET_ERROR_NULL_PTR);
return;
}
conn = new(lws_conn);
conn->ts = srv.accept(impl);
conn->ts->setOnReadable(TCPStream::ReadableHandler_t(this,
&lws_conn_listener::onRX));
if (!conn->ts) {
onError(tl, SOCKET_ERROR_BAD_ALLOC);
if (!conn) {
lwsl_err("OOM\n");
return;
}
conn->ts->setOnError(TCPStream::ErrorHandler_t(this,
&lws_conn_listener::onError));
conn->ts->setOnDisconnect(TCPStream::DisconnectHandler_t(this,
&lws_conn_listener::onDisconnect));
conn->ts->setOnSent(Socket::SentHandler_t(this, &lws_conn_listener::onSent));
conn->ts = ts;
/*
* we use the listen socket wsi to get started, but a new wsi is
* created. mbed3_tcp_stream_accept() is also called from here to
* bind the ts and wsi together
* created. mbed3_tcp_stream_accept() is also called from
* here to bind the conn and new wsi together
*/
lws_server_socket_service(wsi->protocol->owning_server,
wsi, (struct pollfd *)conn);
ts->setOnSent(Socket::SentHandler_t(conn, &lws_conn::onSent));
ts->setOnReadable(TCPStream::ReadableHandler_t(conn, &lws_conn::onRX));
ts->setOnError(TCPStream::ErrorHandler_t(conn, &lws_conn::onError));
ts->setOnDisconnect(TCPStream::DisconnectHandler_t(conn,
&lws_conn::onDisconnect));
/*
* mbed3 is messed up as of 2015-11-08, data packets may
* appear on the listening socket initially
*/
conn->actual_onRX((Socket *)tl);
conn->actual_onRX((Socket *)conn->ts);
lwsl_debug("%s: exit\n", __func__);
}
void lws_conn_listener::onRX(Socket *s)
extern "C" LWS_VISIBLE struct libwebsocket *
wsi_from_fd(struct libwebsocket_context *context, lws_sockfd_type fd)
{
socket_error_t err;
static const char *rsp =
"HTTP/1.1 200 OK\r\n"
"\r\n"
"Ahaha... hello\r\n";
size_t size = BUFFER_SIZE - 1;
int n;
lwsl_notice("%s\r\n", __func__);
err = s->recv(buffer, &size);
n = s->error_check(err);
if (!n) {
buffer[size] = 0;
printf("%d: %s", size, buffer);
lws_conn *conn = (lws_conn *)fd;
(void)context;
err = s->send(rsp, strlen(rsp));
// if (err != SOCKET_ERROR_NONE)
// onError(s, err);
} else
printf("%s: error %d\r\n", __func__, n);
return conn->wsi;
}
extern "C" LWS_VISIBLE void
lws_plat_insert_socket_into_fds(struct libwebsocket_context *context,
struct libwebsocket *wsi)
{
(void)wsi;
lws_libev_io(context, wsi, LWS_EV_START | LWS_EV_READ);
context->fds[context->fds_count++].revents = 0;
}
extern "C" LWS_VISIBLE void
lws_plat_delete_socket_from_fds(struct libwebsocket_context *context,
struct libwebsocket *wsi, int m)
{
(void)context;
(void)wsi;
(void)m;
}
void lws_conn::onRX(Socket *s)
{
actual_onRX(s);
}
void lws_conn_listener::onDisconnect(TCPStream *s)
{
lwsl_notice("%s\r\n", __func__);
lwsl_info("%s\r\n", __func__);
(void)s;
//if (s)
//delete this;
}
void lws_conn_listener::onSent(Socket *s, uint16_t len)
void lws_conn::onSent(Socket *s, uint16_t len)
{
lwsl_notice("%s\r\n", __func__);
struct libwebsocket_pollfd pollfd;
(void)s;
(void)len;
ts->close();
pollfd.fd = this;
pollfd.events = POLLOUT;
pollfd.revents = POLLOUT;
s_HACK = s;
lwsl_debug("%s: wsi %p\r\n", __func__, (void *)wsi);
libwebsocket_service_fd(wsi->protocol->owning_server, &pollfd);
}
void lws_conn_listener::onError(Socket *s, socket_error_t err)
@ -141,3 +243,19 @@ void lws_conn_listener::onError(Socket *s, socket_error_t err)
if (ts)
ts->close();
}
void lws_conn::onDisconnect(TCPStream *s)
{
(void)s;
libwebsocket_close_and_free_session(wsi->protocol->owning_server, wsi,
LWS_CLOSE_STATUS_NOSTATUS);
}
void lws_conn::onError(Socket *s, socket_error_t err)
{
(void) s;
lwsl_notice("Socket Error: %s (%d)\r\n", socket_strerror(err), err);
if (ts)
ts->close();
}

View file

@ -46,9 +46,9 @@ libwebsocket_0405_frame_mask_generate(struct libwebsocket *wsi)
LWS_VISIBLE void lwsl_hexdump(void *vbuf, size_t len)
{
int n;
int m;
int start;
unsigned int n;
unsigned int m;
unsigned int start;
unsigned char *buf = (unsigned char *)vbuf;
char line[80];
char *p;
@ -101,13 +101,12 @@ int lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len)
return 0;
/* just ignore sends after we cleared the truncation buffer */
if (wsi->state == WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE &&
!wsi->truncated_send_len)
!wsi->truncated_send_len)
return len;
if (wsi->truncated_send_len && (buf < wsi->truncated_send_malloc ||
buf > (wsi->truncated_send_malloc +
wsi->truncated_send_len +
wsi->truncated_send_offset))) {
buf > (wsi->truncated_send_malloc + wsi->truncated_send_len +
wsi->truncated_send_offset))) {
lwsl_err("****** %x Sending new, pending truncated ...\n", wsi);
assert(0);
}
@ -133,6 +132,7 @@ int lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len)
switch (n) {
case LWS_SSL_CAPABLE_ERROR:
lwsl_err("%s: wsi %p: LWS_SSL_CAPABLE_ERROR\n", __func__, (void *)wsi);
/* we're going to close, let close know sends aren't possible */
wsi->socket_is_permanently_unusable = 1;
return -1;
@ -578,6 +578,7 @@ all_sent:
return 0; /* indicates further processing must be done */
}
#if LWS_POSIX
LWS_VISIBLE int
lws_ssl_capable_read_no_ssl(struct libwebsocket_context *context,
struct libwebsocket *wsi, unsigned char *buf, int len)
@ -585,21 +586,15 @@ lws_ssl_capable_read_no_ssl(struct libwebsocket_context *context,
int n;
(void)context;
#if LWS_POSIX
n = recv(wsi->sock, (char *)buf, len, 0);
if (n >= 0)
return n;
#if LWS_POSIX
if (LWS_ERRNO == LWS_EAGAIN ||
LWS_ERRNO == LWS_EWOULDBLOCK ||
LWS_ERRNO == LWS_EINTR)
return LWS_SSL_CAPABLE_MORE_SERVICE;
#else
(void)n;
(void)wsi;
(void)buf;
(void)len;
// !!!
#endif
lwsl_warn("error on reading from skt\n");
return LWS_SSL_CAPABLE_ERROR;
@ -608,7 +603,7 @@ lws_ssl_capable_read_no_ssl(struct libwebsocket_context *context,
LWS_VISIBLE int
lws_ssl_capable_write_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len)
{
int n;
int n = 0;
#if LWS_POSIX
n = send(wsi->sock, (char *)buf, len, MSG_NOSIGNAL);
@ -634,7 +629,7 @@ lws_ssl_capable_write_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int l
lwsl_debug("ERROR writing len %d to skt %d\n", len, n);
return LWS_SSL_CAPABLE_ERROR;
}
#endif
LWS_VISIBLE int
lws_ssl_pending_no_ssl(struct libwebsocket *wsi)
{

View file

@ -25,7 +25,6 @@ int
insert_wsi_socket_into_fds(struct libwebsocket_context *context,
struct libwebsocket *wsi)
{
#if LWS_POSIX
struct libwebsocket_pollargs pa = { wsi->sock, LWS_POLLIN, 0 };
if (context->fds_count >= context->max_fds) {
@ -44,8 +43,8 @@ insert_wsi_socket_into_fds(struct libwebsocket_context *context,
assert(wsi);
assert(lws_socket_is_valid(wsi->sock));
lwsl_info("insert_wsi_socket_into_fds: wsi=%p, sock=%d, fds pos=%d\n",
wsi, wsi->sock, context->fds_count);
// lwsl_info("insert_wsi_socket_into_fds: wsi=%p, sock=%d, fds pos=%d\n",
// wsi, wsi->sock, context->fds_count);
if (context->protocols[0].callback(context, wsi,
LWS_CALLBACK_LOCK_POLL, wsi->user_space, (void *) &pa, 0))
@ -66,9 +65,6 @@ insert_wsi_socket_into_fds(struct libwebsocket_context *context,
if (context->protocols[0].callback(context, wsi,
LWS_CALLBACK_UNLOCK_POLL, wsi->user_space, (void *)&pa, 0))
return -1;
#endif
(void)context;
(void)wsi;
return 0;
}
@ -77,7 +73,6 @@ int
remove_wsi_socket_from_fds(struct libwebsocket_context *context,
struct libwebsocket *wsi)
{
#if LWS_POSIX
int m;
struct libwebsocket_pollargs pa = { wsi->sock, 0, 0 };
@ -130,10 +125,6 @@ remove_wsi_socket_from_fds(struct libwebsocket_context *context,
LWS_CALLBACK_UNLOCK_POLL,
wsi->user_space, (void *) &pa, 0))
return -1;
#endif
(void)context;
(void)wsi;
return 0;
}

View file

@ -195,6 +195,15 @@
#if defined(MBED_OPERATORS)
#undef compatible_close
#define compatible_close(fd) mbed3_delete_tcp_stream_socket(fd)
#ifndef BIG_ENDIAN
#define BIG_ENDIAN 4321 /* to show byte order (taken from gcc) */
#endif
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 1234
#endif
#ifndef BYTE_ORDER
#define BYTE_ORDER LITTLE_ENDIAN
#endif
#endif
#if defined(WIN32) || defined(_WIN32)
@ -208,7 +217,9 @@
#ifndef BYTE_ORDER
#define BYTE_ORDER LITTLE_ENDIAN
#endif
#ifndef u_int64_t
typedef unsigned __int64 u_int64_t;
#endif
#undef __P
#ifndef __P
@ -295,7 +306,7 @@ extern "C" {
#define SPEC_LATEST_SUPPORTED 13
#endif
#ifndef AWAITING_TIMEOUT
#define AWAITING_TIMEOUT 5
#define AWAITING_TIMEOUT 20
#endif
#ifndef CIPHERS_LIST_STRING
#define CIPHERS_LIST_STRING "DEFAULT"

View file

@ -728,6 +728,7 @@ int lws_server_socket_service(struct libwebsocket_context *context,
len = lws_ssl_capable_read(context, wsi,
context->service_buffer,
sizeof(context->service_buffer));
lwsl_debug("%s: read %d\r\n", __func__, len);
switch (len) {
case 0:
lwsl_info("lws_server_skt_srv: read 0 len\n");
@ -864,9 +865,10 @@ try_pollout:
lws_libev_accept(context, new_wsi, accept_fd);
if (!LWS_SSL_ENABLED(context)) {
#if LWS_POSIX
lwsl_debug("accepted new conn port %u on fd=%d\n",
ntohs(cli_addr.sin_port), accept_fd);
#endif
if (insert_wsi_socket_into_fds(context, new_wsi))
goto fail;
}

View file

@ -298,7 +298,7 @@ libwebsocket_service_timeout_check(struct libwebsocket_context *context,
* connection
*/
if ((time_t)sec > wsi->pending_timeout_limit) {
lwsl_info("TIMEDOUT WAITING on %d\n", wsi->pending_timeout);
lwsl_info("wsi %p: TIMEDOUT WAITING on %d\n", (void *)wsi, wsi->pending_timeout);
/*
* Since he failed a timeout, he already had a chance to do
* something and was unable to... that includes situations like
@ -364,7 +364,9 @@ libwebsocket_service_fd(struct libwebsocket_context *context,
struct libwebsocket *wsi;
int n, m;
lws_sockfd_type mfd;
#if LWS_POSIX
int listen_socket_fds_index = 0;
#endif
time_t now;
int timed_out = 0;
lws_sockfd_type our_fd = 0;
@ -373,9 +375,10 @@ libwebsocket_service_fd(struct libwebsocket_context *context,
struct lws_tokens eff_buf;
unsigned int pending = 0;
#if LWS_POSIX
if (context->listen_service_fd)
listen_socket_fds_index = wsi_from_fd(context,context->listen_service_fd)->position_in_fds_table;
#endif
/*
* you can call us with pollfd = NULL to just allow the once-per-second
* global timeout checks; if less than a second since the last check
@ -430,6 +433,7 @@ libwebsocket_service_fd(struct libwebsocket_context *context,
* zero down pollfd->revents after handling
*/
#if LWS_POSIX
/*
* deal with listen service piggybacking
* every listen_service_modulo services of other fds, we
@ -481,6 +485,7 @@ libwebsocket_service_fd(struct libwebsocket_context *context,
goto close_and_handled;
}
#endif
/* okay, what we came here to do... */

View file

@ -468,7 +468,7 @@ lws_ssl_capable_read(struct libwebsocket_context *context,
n = SSL_get_error(wsi->ssl, n);
if (n == SSL_ERROR_WANT_READ || n == SSL_ERROR_WANT_WRITE)
return LWS_SSL_CAPABLE_MORE_SERVICE;
lwsl_err("%s: LWS_SSL_CAPABLE_ERROR\n", __func__);
return LWS_SSL_CAPABLE_ERROR;
}
@ -488,7 +488,7 @@ lws_ssl_capable_write(struct libwebsocket *wsi, unsigned char *buf, int len)
if (!wsi->ssl)
return lws_ssl_capable_write_no_ssl(wsi, buf, len);
n = SSL_write(wsi->ssl, buf, len);
if (n >= 0)
return n;
@ -499,7 +499,7 @@ lws_ssl_capable_write(struct libwebsocket *wsi, unsigned char *buf, int len)
lws_set_blocking_send(wsi);
return LWS_SSL_CAPABLE_MORE_SERVICE;
}
lwsl_err("%s: LWS_SSL_CAPABLE_ERROR\n", __func__);
return LWS_SSL_CAPABLE_ERROR;
}