diff --git a/mongoose.c b/mongoose.c
index 140dddd1792a7828ebb8558058d72349a53e4e89..284231487522a534fcbe66c6fcbd34704184ad68 100644
--- a/mongoose.c
+++ b/mongoose.c
@@ -3,6 +3,7 @@
 // All rights reserved
 //
 // This library is dual-licensed: you can redistribute it and/or modify
+
 // it under the terms of the GNU General Public License version 2 as
 // published by the Free Software Foundation. For the terms of this
 // license, see <http://www.gnu.org/licenses/>.
@@ -213,6 +214,7 @@ void ns_server_init(struct ns_server *, void *server_data, ns_callback_t);
 void ns_server_free(struct ns_server *);
 int ns_server_poll(struct ns_server *, int milli);
 void ns_server_wakeup(struct ns_server *);
+void ns_server_wakeup_ex(struct ns_server *, ns_callback_t, void *, size_t);
 void ns_iterate(struct ns_server *, ns_callback_t cb, void *param);
 struct ns_connection *ns_add_sock(struct ns_server *, sock_t sock, void *p);
 
@@ -268,6 +270,11 @@ int ns_hexdump(const void *buf, int len, char *dst, int dst_len);
 #define NS_FREE free
 #endif
 
+struct ctl_msg {
+  ns_callback_t callback;
+  char message[1024 * 8];
+};
+
 void iobuf_init(struct iobuf *iobuf, size_t size) {
   iobuf->len = iobuf->size = 0;
   iobuf->buf = NULL;
@@ -871,9 +878,12 @@ int ns_server_poll(struct ns_server *server, int milli) {
     // Read possible wakeup calls
     if (server->ctl[1] != INVALID_SOCKET &&
         FD_ISSET(server->ctl[1], &read_set)) {
-      unsigned char ch;
-      recv(server->ctl[1], &ch, 1, 0);
-      send(server->ctl[1], &ch, 1, 0);
+      struct ctl_msg ctl_msg;
+      int len = recv(server->ctl[1], &ctl_msg, sizeof(ctl_msg), 0);
+      send(server->ctl[1], ctl_msg.message, 1, 0);
+      if (len >= (int) sizeof(ctl_msg.callback) && ctl_msg.callback != NULL) {
+        ns_iterate(server, ctl_msg.callback, ctl_msg.message);
+      }
     }
 
     for (conn = server->active_connections; conn != NULL; conn = tmp_conn) {
@@ -980,14 +990,22 @@ void ns_iterate(struct ns_server *server, ns_callback_t cb, void *param) {
   }
 }
 
-void ns_server_wakeup(struct ns_server *server) {
-  unsigned char ch = 0;
-  if (server->ctl[0] != INVALID_SOCKET) {
-    send(server->ctl[0], &ch, 1, 0);
-    recv(server->ctl[0], &ch, 1, 0);
+void ns_server_wakeup_ex(struct ns_server *server, ns_callback_t cb,
+                         void *data, size_t len) {
+  struct ctl_msg ctl_msg;
+  if (server->ctl[0] != INVALID_SOCKET && data != NULL &&
+      len < sizeof(ctl_msg.message)) {
+    ctl_msg.callback = cb;
+    memcpy(ctl_msg.message, data, len);
+    send(server->ctl[0], &ctl_msg, offsetof(struct ctl_msg, message) + len, 0);
+    recv(server->ctl[0], &len, 1, 0);
   }
 }
 
+void ns_server_wakeup(struct ns_server *server) {
+  ns_server_wakeup_ex(server, NULL, (void *) "", 0);
+}
+
 void ns_server_init(struct ns_server *s, void *server_data, ns_callback_t cb) {
   memset(s, 0, sizeof(*s));
   s->listening_sock = s->ctl[0] = s->ctl[1] = INVALID_SOCKET;
@@ -1004,7 +1022,7 @@ void ns_server_init(struct ns_server *s, void *server_data, ns_callback_t cb) {
 
 #ifndef NS_DISABLE_SOCKETPAIR
   do {
-    ns_socketpair(s->ctl);
+    ns_socketpair2(s->ctl, SOCK_DGRAM);
   } while (s->ctl[0] == INVALID_SOCKET);
 #endif
 
@@ -1173,7 +1191,6 @@ enum {
 #endif
 #ifdef NS_ENABLE_SSL
   SSL_CERTIFICATE,
-  SSL_CA_CERTIFICATE,
 #endif
   URL_REWRITES,
   NUM_OPTIONS
@@ -1214,7 +1231,6 @@ static const char *static_config_options[] = {
 #endif
 #ifdef NS_ENABLE_SSL
   "ssl_certificate", NULL,
-  "ssl_ca_certificate", NULL,
 #endif
   "url_rewrites", NULL,
   NULL
@@ -4545,10 +4561,6 @@ const char *mg_set_option(struct mg_server *server, const char *name,
     } else if (res == -1) {
       error_msg = "SSL_CTX_new() failed";
     }
-  } else if (ind == SSL_CA_CERTIFICATE) {
-    if (ns_set_ssl_ca_cert(&server->ns_server, value) != 0) {
-      error_msg = "Error setting CA cert";
-    }
 #endif
   }
 
@@ -4716,8 +4728,38 @@ static void mg_ev_handler(struct ns_connection *nc, enum ns_event ev, void *p) {
   }
 }
 
+static void iter2(struct ns_connection *nc, enum ns_event ev, void *param) {
+  mg_handler_t func = NULL;
+  struct connection *conn = (struct connection *) nc->connection_data;
+  const char *msg = (const char *) param;
+  int n;
+  (void) ev;
+
+  DBG(("%p [%s]", conn, msg));
+  if (sscanf(msg, "%p %n", &func, &n) && func != NULL) {
+    conn->mg_conn.callback_param = (void *) (msg + n);
+    func(&conn->mg_conn, MG_POLL);
+  }
+}
+
+void mg_wakeup_server_ex(struct mg_server *server, mg_handler_t cb,
+                         const char *fmt, ...) {
+  va_list ap;
+  char buf[8 * 1024];
+  int len;
+
+  // Encode callback (cb) into a buffer
+  len = snprintf(buf, sizeof(buf), "%p ", cb);
+  va_start(ap, fmt);
+  len += vsnprintf(buf + len, sizeof(buf) - len, fmt, ap);
+  va_end(ap);
+
+  // "len + 1" is to include terminating \0 in the message
+  ns_server_wakeup_ex(&server->ns_server, iter2, buf, len + 1);
+}
+
 void mg_wakeup_server(struct mg_server *server) {
-  ns_server_wakeup(&server->ns_server);
+  ns_server_wakeup_ex(&server->ns_server, NULL, (void *) "", 0);
 }
 
 void mg_set_listening_socket(struct mg_server *server, int sock) {
diff --git a/mongoose.h b/mongoose.h
index 0fd4251de81074c187e210e00f73225bf65cd71e..18afc2ff7adb03a9f82495f892f3f01e712bd74e 100644
--- a/mongoose.h
+++ b/mongoose.h
@@ -93,6 +93,7 @@ void mg_set_listening_socket(struct mg_server *, int sock);
 int mg_get_listening_socket(struct mg_server *);
 void mg_iterate_over_connections(struct mg_server *, mg_handler_t, void *);
 void mg_wakeup_server(struct mg_server *);
+void mg_wakeup_server_ex(struct mg_server *, mg_handler_t, const char *, ...);
 struct mg_connection *mg_connect(struct mg_server *, const char *, int, int);
 
 // Connection management functions