add lws_confirm_legit_wsi

Signed-off-by: Andy Green <andy.green@linaro.org>
diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c
index 000861c..333db4c 100644
--- a/lib/libwebsockets.c
+++ b/lib/libwebsockets.c
@@ -2117,6 +2117,38 @@
 	return wsi->user_space;
 }
 
+/**
+ * lws_confirm_legit_wsi: returns nonzero if the wsi looks bad
+ *
+ * @wsi: struct libwebsocket to assess
+ *
+ * Performs consistecy checks on what the wsi claims and what the
+ * polling arrays hold.  This'll catch a closed wsi still in use.
+ * Don't try to use on the listen (nonconnection) wsi as it will
+ * fail it.  Otherwise 0 return == wsi seems consistent.
+ */
+
+int lws_confirm_legit_wsi(struct libwebsocket *wsi)
+{
+	struct libwebsocket_context *context;
+
+	if (!(wsi && wsi->protocol && wsi->protocol->owning_server))
+		return 1;
+
+	context = wsi->protocol->owning_server;
+
+	if (!context)
+		return 2;
+
+	if (!wsi->position_in_fds_table)
+		return 3; /* position in fds table looks bad */
+	if (context->fds[wsi->position_in_fds_table].fd != wsi->sock)
+		return 4; /* pollfd entry does not wait on our socket descriptor */
+	if (context->lws_lookup[wsi->sock] != wsi)
+		return 5; /* lookup table does not agree with wsi */
+
+	return 0;
+}
 
 static void lwsl_emit_stderr(const char *line)
 {
diff --git a/lib/output.c b/lib/output.c
index 68fd312..eff467c 100644
--- a/lib/output.c
+++ b/lib/output.c
@@ -295,6 +295,10 @@
 	struct lws_tokens eff_buf;
 	int m;
 
+	if (lws_confirm_legit_wsi(wsi)) {
+		lwsl_err("libwebsocket_write on illegitimate wsi\n");
+		return -1;
+	}
 	if (len == 0 && protocol != LWS_WRITE_CLOSE) {
 		lwsl_warn("zero length libwebsocket_write attempt\n");
 		return 0;
diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h
index 4f6400d..a3047f7 100644
--- a/lib/private-libwebsockets.h
+++ b/lib/private-libwebsockets.h
@@ -492,6 +492,9 @@
 _libwebsocket_rx_flow_control(struct libwebsocket *wsi);
 
 extern int
+lws_confirm_legit_wsi(struct libwebsocket *wsi);
+
+extern int
 user_callback_handle_rxflow(callback_function, struct libwebsocket_context * context,
 			struct libwebsocket *wsi,
 			 enum libwebsocket_callback_reasons reason, void *user,
diff --git a/libwebsockets-api-doc.html b/libwebsockets-api-doc.html
index 73aefe8..6acd4f3 100644
--- a/libwebsockets-api-doc.html
+++ b/libwebsockets-api-doc.html
@@ -350,6 +350,23 @@
 "just work".
 </blockquote>
 <hr>
+<h2>lws_confirm_legit_wsi - </h2>
+<i>int</i>
+<b>lws_confirm_legit_wsi</b>
+(<i>struct libwebsocket *</i> <b>wsi</b>)
+<h3>Arguments</h3>
+<dl>
+<dt><b>wsi</b>
+<dd>struct libwebsocket to assess
+</dl>
+<h3>Description</h3>
+<blockquote>
+Performs consistecy checks on what the wsi claims and what the
+polling arrays hold.  This'll catch a closed wsi still in use.
+Don't try to use on the listen (nonconnection) wsi as it will
+fail it.  Otherwise 0 return == wsi seems consistent.
+</blockquote>
+<hr>
 <h2>lws_set_log_level - Set the logging bitfield</h2>
 <i>void</i>
 <b>lws_set_log_level</b>