#else
lwsl_notice("IPV6 not compiled in\n");
#endif
-#endif
lws_feature_status_libev(info);
+#endif
lwsl_info(" LWS_MAX_HEADER_LEN: %u\n", LWS_MAX_HEADER_LEN);
lwsl_info(" LWS_MAX_PROTOCOLS: %u\n", LWS_MAX_PROTOCOLS);
/* to reduce this allocation, */
context->max_fds = getdtablesize();
- lwsl_notice(" static allocation: %u + (%u x %u fds) = %u bytes\n",
- sizeof(struct lws_context),
- sizeof(struct lws_pollfd) +
- sizeof(struct lws *),
- context->max_fds,
- sizeof(struct lws_context) +
- ((sizeof(struct lws_pollfd) +
- sizeof(struct lws *)) *
- context->max_fds));
-
- context->fds = lws_zalloc(sizeof(struct lws_pollfd) *
- context->max_fds);
+ lwsl_notice(" ctx mem: %u bytes\n", sizeof(struct lws_context) +
+ ((sizeof(struct lws_pollfd) + sizeof(struct lws *)) *
+ context->max_fds));
+
+ context->fds = lws_zalloc(sizeof(struct lws_pollfd) * context->max_fds);
if (context->fds == NULL) {
- lwsl_err("Unable to allocate fds array for %d connections\n",
- context->max_fds);
+ lwsl_err("OOM allocating %d fds\n", context->max_fds);
goto bail;
}
#endif
}
- lwsl_notice(
- " per-conn mem: %u + %u headers + protocol rx buf\n",
- sizeof(struct lws),
- sizeof(struct allocated_headers));
+ lwsl_notice(" per-conn mem: %u + %u headers + protocol rx buf\n",
+ sizeof(struct lws), sizeof(struct allocated_headers));
if (lws_context_init_server_ssl(info, context))
goto bail;
/* initialize supported protocols */
for (context->count_protocols = 0;
- info->protocols[context->count_protocols].callback;
- context->count_protocols++) {
-
-// lwsl_notice(" Protocol: %s\n",
-// info->protocols[context->count_protocols].name);
-
+ info->protocols[context->count_protocols].callback;
+ context->count_protocols++) {
info->protocols[context->count_protocols].owning_server =
context;
info->protocols[context->count_protocols].protocol_index =
* give all extensions a chance to create any per-context
* allocations they need
*/
-
if (info->port != CONTEXT_PORT_NO_LISTEN) {
if (lws_ext_callback_for_each_extension_type(context, NULL,
- LWS_EXT_CALLBACK_SERVER_CONTEXT_CONSTRUCT,
- NULL, 0) < 0)
+ LWS_EXT_CALLBACK_SERVER_CONTEXT_CONSTRUCT, NULL, 0) < 0)
goto bail;
} else
if (lws_ext_callback_for_each_extension_type(context, NULL,
- LWS_EXT_CALLBACK_CLIENT_CONTEXT_CONSTRUCT,
- NULL, 0) < 0)
+ LWS_EXT_CALLBACK_CLIENT_CONTEXT_CONSTRUCT, NULL, 0) < 0)
goto bail;
return context;
LWS_VISIBLE void
lws_context_destroy(struct lws_context *context)
{
- /* Note that this is used for freeing partially allocated structs as well
- * so make sure you don't try to free something uninitialized */
- int n;
struct lws_protocols *protocol = NULL;
+ int n;
lwsl_notice("%s\n", __func__);
#endif
for (n = 0; n < context->fds_count; n++) {
- struct lws *wsi =
- wsi_from_fd(context, context->fds[n].fd);
+ struct lws *wsi = wsi_from_fd(context, context->fds[n].fd);
if (!wsi)
continue;
- lws_close_and_free_session(context,
- wsi, LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY /* no protocol close */);
+ lws_close_and_free_session(context, wsi,
+ LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY
+ /* no protocol close */);
n--;
}
* give all extensions a chance to clean up any per-context
* allocations they might have made
*/
- // TODO: I am not sure, but are we never supposed to be able to run a server
- // and client at the same time for a given context?
- // Otherwise both of these callbacks should always be called!
- if (context->listen_port != CONTEXT_PORT_NO_LISTEN) {
- if (lws_ext_callback_for_each_extension_type(context, NULL,
- LWS_EXT_CALLBACK_SERVER_CONTEXT_DESTRUCT, NULL, 0) < 0) {
- lwsl_err("Got error from server extension callback on cleanup");
- }
- } else {
- if (lws_ext_callback_for_each_extension_type(context, NULL,
- LWS_EXT_CALLBACK_CLIENT_CONTEXT_DESTRUCT, NULL, 0) < 0) {
- lwsl_err("Got error from client extension callback on cleanup");
- }
- }
+
+ n = lws_ext_callback_for_each_extension_type(context, NULL,
+ LWS_EXT_CALLBACK_SERVER_CONTEXT_DESTRUCT, NULL, 0);
+
+ n = lws_ext_callback_for_each_extension_type(context, NULL,
+ LWS_EXT_CALLBACK_CLIENT_CONTEXT_DESTRUCT, NULL, 0);
/*
* inform all the protocols that they are done and will have no more
protocol = context->protocols;
if (protocol) {
while (protocol->callback) {
- protocol->callback(context, NULL, LWS_CALLBACK_PROTOCOL_DESTROY,
- NULL, NULL, 0);
+ protocol->callback(context, NULL,
+ LWS_CALLBACK_PROTOCOL_DESTROY,
+ NULL, NULL, 0);
protocol++;
}
}
return;
/* Protocol user data may be allocated either internally by lws
- * or by specified the user. Important we don't free external user data */
- if (wsi->protocol && wsi->protocol->per_session_data_size
- && wsi->user_space && !wsi->user_space_externally_allocated) {
+ * or by specified the user.
+ * We should only free what we allocated. */
+ if (wsi->protocol && wsi->protocol->per_session_data_size &&
+ wsi->user_space && !wsi->user_space_externally_allocated)
lws_free(wsi->user_space);
- }
lws_free2(wsi->rxflow_buffer);
lws_free2(wsi->truncated_send_malloc);
-
- // TODO: Probably should handle the union structs in wsi->u here depending
- // on connection mode as well. Too spaghetti for me to follow however...
-
lws_free_header_table(wsi);
lws_free(wsi);
}
lws_close_and_free_session(struct lws_context *context,
struct lws *wsi, enum lws_close_status reason)
{
- int n, m, ret;
- int old_state;
- unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2 +
- LWS_SEND_BUFFER_POST_PADDING];
+ int n, m, ret, old_state;
struct lws_tokens eff_buf;
+ unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2 +
+ LWS_SEND_BUFFER_POST_PADDING];
if (!wsi)
return;
old_state = wsi->state;
+ if (wsi->mode == LWS_CONNMODE_HTTP_SERVING_ACCEPTED &&
+ wsi->u.http.fd != LWS_INVALID_FILE) {
+ lwsl_debug("closing http file\n");
+ compatible_file_close(wsi->u.http.fd);
+ wsi->u.http.fd = LWS_INVALID_FILE;
+ context->protocols[0].callback(context, wsi,
+ LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0);
+ }
if (wsi->socket_is_permanently_unusable ||
reason == LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY)
goto just_kill_connection;
wsi->u.ws.close_reason = reason;
if (wsi->mode == LWS_CONNMODE_WS_CLIENT_WAITING_CONNECT ||
- wsi->mode == LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE)
+ wsi->mode == LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE)
goto just_kill_connection;
if (wsi->mode == LWS_CONNMODE_HTTP_SERVING)
context->protocols[0].callback(context, wsi,
LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0);
- if (wsi->mode == LWS_CONNMODE_HTTP_SERVING_ACCEPTED) {
- if (wsi->u.http.fd != LWS_INVALID_FILE) {
- // TODO: If we're just closing with LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY this file descriptor might leak?
- lwsl_debug("closing http file\n");
- compatible_file_close(wsi->u.http.fd);
- wsi->u.http.fd = LWS_INVALID_FILE;
- context->protocols[0].callback(context, wsi,
- LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0);
- }
- }
-
/*
* are his extensions okay with him closing? Eg he might be a mux
* parent and just his ch1 aspect is closing?
if (eff_buf.token_len)
if (lws_issue_raw(wsi, (unsigned char *)eff_buf.token,
- eff_buf.token_len) != eff_buf.token_len) {
+ eff_buf.token_len) !=
+ eff_buf.token_len) {
lwsl_debug("close: ext spill failed\n");
goto just_kill_connection;
}
/* make valgrind happy */
memset(buf, 0, sizeof(buf));
- n = lws_write(wsi,
- &buf[LWS_SEND_BUFFER_PRE_PADDING + 2],
- 0, LWS_WRITE_CLOSE);
+ n = lws_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING + 2],
+ 0, LWS_WRITE_CLOSE);
if (n >= 0) {
/*
* we have sent a nice protocol level indication we
* now wish to close, we should not send anything more
*/
-
wsi->state = WSI_STATE_AWAITING_CLOSE_ACK;
/*
* ...and we should wait for a reply for a bit
* out of politeness
*/
-
- lws_set_timeout(wsi,
- PENDING_TIMEOUT_CLOSE_ACK, 1);
-
+ lws_set_timeout(wsi, PENDING_TIMEOUT_CLOSE_ACK, 1);
lwsl_debug("sent close indication, awaiting ack\n");
return;
* we won't be servicing or receiving anything further from this guy
* delete socket from the internal poll list if still present
*/
-
lws_ssl_remove_wsi_from_buffered_list(context, wsi);
- // checking return redundant since we anyway close
+ /* checking return redundant since we anyway close */
remove_wsi_socket_from_fds(context, wsi);
wsi->state = WSI_STATE_DEAD_SOCKET;
lws_free2(wsi->u.ws.rx_user_buffer);
- if (wsi->truncated_send_malloc) {
+ if (wsi->truncated_send_malloc)
/* not going to be completed... nuke it */
lws_free2(wsi->truncated_send_malloc);
- wsi->truncated_send_len = 0;
- }
+
if (wsi->u.ws.ping_payload_buf) {
lws_free2(wsi->u.ws.ping_payload_buf);
wsi->u.ws.ping_payload_alloc = 0;
/* tell the user it's all over for this guy */
if (wsi->protocol && wsi->protocol->callback &&
- ((old_state == WSI_STATE_ESTABLISHED) ||
- (old_state == WSI_STATE_RETURNED_CLOSE_ALREADY) ||
- (old_state == WSI_STATE_AWAITING_CLOSE_ACK) ||
- (old_state == WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE))) {
+ ((old_state == WSI_STATE_ESTABLISHED) ||
+ (old_state == WSI_STATE_RETURNED_CLOSE_ALREADY) ||
+ (old_state == WSI_STATE_AWAITING_CLOSE_ACK) ||
+ (old_state == WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE))) {
lwsl_debug("calling back CLOSED\n");
wsi->protocol->callback(context, wsi, LWS_CALLBACK_CLOSED,
- wsi->user_space, NULL, 0);
+ wsi->user_space, NULL, 0);
} else if (wsi->mode == LWS_CONNMODE_HTTP_SERVING_ACCEPTED) {
lwsl_debug("calling back CLOSED_HTTP\n");
context->protocols[0].callback(context, wsi,
wsi->mode == LWS_CONNMODE_WS_CLIENT_WAITING_CONNECT) {
lwsl_debug("Connection closed before server reply\n");
context->protocols[0].callback(context, wsi,
- LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
- wsi->user_space, NULL, 0 );
+ LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
+ wsi->user_space, NULL, 0);
} else
lwsl_debug("not calling back closed mode=%d state=%d\n",
wsi->mode, old_state);
/* deallocate any active extension contexts */
- if (lws_ext_callback_for_each_active(wsi, LWS_EXT_CALLBACK_DESTROY, NULL, 0) < 0)
+ if (lws_ext_callback_for_each_active(wsi, LWS_EXT_CALLBACK_DESTROY,
+ NULL, 0) < 0)
lwsl_warn("extension destruction failed\n");
#ifndef LWS_NO_EXTENSIONS
for (n = 0; n < wsi->count_active_extensions; n++)
LWS_EXT_CALLBACK_DESTROY_ANY_WSI_CLOSING, NULL, 0) < 0)
lwsl_warn("ext destroy wsi failed\n");
-/* lwsl_info("closing fd=%d\n", wsi->sock); */
-
if (!lws_ssl_close(wsi) && lws_socket_is_valid(wsi->sock)) {
#if LWS_POSIX
n = shutdown(wsi->sock, SHUT_RDWR);
}
/* outermost destroy notification for wsi (user_space still intact) */
- context->protocols[0].callback(context, wsi,
- LWS_CALLBACK_WSI_DESTROY, wsi->user_space, NULL, 0);
+ context->protocols[0].callback(context, wsi, LWS_CALLBACK_WSI_DESTROY,
+ wsi->user_space, NULL, 0);
lws_free_wsi(wsi);
}
*/
LWS_VISIBLE int
-lws_callback_all_protocol(
- const struct lws_protocols *protocol, int reason)
+lws_callback_all_protocol(const struct lws_protocols *protocol, int reason)
{
struct lws_context *context = protocol->owning_server;
- int n;
struct lws *wsi;
+ int n;
for (n = 0; n < context->fds_count; n++) {
wsi = wsi_from_fd(context, context->fds[n].fd);
continue;
if (wsi->protocol == protocol)
protocol->callback(context, wsi,
- reason, wsi->user_space, NULL, 0);
+ reason, wsi->user_space, NULL, 0);
}
return 0;
*/
LWS_VISIBLE void
-lws_set_timeout(struct lws *wsi,
- enum pending_timeout reason, int secs)
+lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs)
{
time_t now;
if (enable == (wsi->rxflow_change_to & LWS_RXFLOW_ALLOW))
return 0;
- lwsl_info("lws_rx_flow_control(0x%p, %d)\n", wsi, enable);
+ lwsl_info("%s: (0x%p, %d)\n", __func__, wsi, enable);
wsi->rxflow_change_to = LWS_RXFLOW_PENDING_CHANGE | !!enable;
return 0;
return 1;
}
} else
- lwsl_info("%s: %p protocol pss %u, user_space=%d\n", __func__, wsi, wsi->protocol->per_session_data_size, wsi->user_space);
+ lwsl_info("%s: %p protocol pss %u, user_space=%d\n",
+ __func__, wsi, wsi->protocol->per_session_data_size,
+ wsi->user_space);
return 0;
}
+#if LWS_POSIX
LWS_VISIBLE void lwsl_emit_stderr(int level, const char *line)
{
- char buf[300];
unsigned long long now;
+ char buf[300];
int n;
buf[0] = '\0';
- for (n = 0; n < LLL_COUNT; n++)
- if (level == (1 << n)) {
- now = time_in_microseconds() / 100;
- sprintf(buf, "[%llu:%04d] %s: ", (unsigned long long) now / 10000,
- (int)(now % 10000), log_level_names[n]);
- break;
- }
+ for (n = 0; n < LLL_COUNT; n++) {
+ if (level != (1 << n))
+ continue;
+ now = time_in_microseconds() / 100;
+ sprintf(buf, "[%llu:%04d] %s: ",
+ (unsigned long long) now / 10000,
+ (int)(now % 10000), log_level_names[n]);
+ break;
+ }
fprintf(stderr, "%s%s", buf, line);
}
-
+#endif
LWS_VISIBLE void _lws_logv(int filter, const char *format, va_list vl)
{
*/
LWS_VISIBLE void lws_set_log_level(int level,
- void (*log_emit_function)(int level,
- const char *line))
+ void (*func)(int level, const char *line))
{
log_level = level;
- if (log_emit_function)
- lwsl_emit = log_emit_function;
+ if (func)
+ lwsl_emit = func;
}
/**
#ifdef LWS_USE_LIBEV
#undef libwebsocket_sigint_cfg
LWS_VISIBLE LWS_EXTERN int
-libwebsocket_sigint_cfg(
- struct lws_context *context,
- int use_ev_sigint,
- lws_ev_signal_cb* cb)
+libwebsocket_sigint_cfg(struct lws_context *context, int use_ev_sigint,
+ lws_ev_signal_cb* cb)
{
return lws_sigint_cfg(context, use_ev_sigint, cb);
}