}
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);
/*
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;
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;
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",
if (lws_plat_init_fd_tables(context)) {
goto bail;
}
-#endif
+
lws_context_init_extensions(info, context);
context->user_space = info->user;
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;
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) */
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);
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;
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" {
#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)
#else
#if defined(MBED_OPERATORS)
+/* it's a class lws_conn * */
typedef void * lws_sockfd_type;
#define lws_sockfd_valid(sfd) (!!sfd)
struct pollfd {
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
#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);
{
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.
*/
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.
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;
+
+ return conn->wsi;
+}
- err = s->send(rsp, strlen(rsp));
-// if (err != SOCKET_ERROR_NONE)
-// onError(s, err);
- } else
- printf("%s: error %d\r\n", __func__, n);
+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)
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();
+}
\ No newline at end of file
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;
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);
}
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;
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)
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;
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);
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)
{
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) {
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))
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;
}
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 };
LWS_CALLBACK_UNLOCK_POLL,
wsi->user_space, (void *) &pa, 0))
return -1;
-#endif
-
- (void)context;
- (void)wsi;
return 0;
}
#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)
#ifndef BYTE_ORDER
#define BYTE_ORDER LITTLE_ENDIAN
#endif
+#ifndef u_int64_t
typedef unsigned __int64 u_int64_t;
+#endif
#undef __P
#ifndef __P
#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"
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");
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;
}
* 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
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;
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
* zero down pollfd->revents after handling
*/
+#if LWS_POSIX
/*
* deal with listen service piggybacking
* every listen_service_modulo services of other fds, we
goto close_and_handled;
}
+#endif
/* okay, what we came here to do... */
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;
}
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;
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;
}