void mg_lwip_ssl_do_hs(struct mg_connection *nc) { struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; int server_side = (nc->listener != NULL); enum mg_ssl_if_result res; if (nc->flags & MG_F_CLOSE_IMMEDIATELY) return; res = mg_ssl_if_handshake(nc); DBG(("%p %lu %d %d", nc, nc->flags, server_side, res)); if (res != MG_SSL_OK) { if (res == MG_SSL_WANT_WRITE) { nc->flags |= MG_F_WANT_WRITE; cs->err = 0; } else if (res == MG_SSL_WANT_READ) { /* * Nothing to do in particular, we are callback-driven. * What we definitely do not need anymore is SSL reading (nothing left). */ nc->flags &= ~MG_F_WANT_READ; cs->err = 0; } else { cs->err = res; if (server_side) { mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc); } else { mg_lwip_post_signal(MG_SIG_CONNECT_RESULT, nc); } } } else { cs->err = 0; nc->flags &= ~MG_F_WANT_WRITE; /* * Handshake is done. Schedule a read immediately to consume app data * which may already be waiting. */ nc->flags |= (MG_F_SSL_HANDSHAKE_DONE | MG_F_WANT_READ); if (server_side) { mg_lwip_accept_conn(nc, cs->pcb.tcp); } else { mg_lwip_post_signal(MG_SIG_CONNECT_RESULT, nc); } } }
static void mg_ssl_begin(struct mg_connection *nc) { int server_side = (nc->listener != NULL); enum mg_ssl_if_result res = mg_ssl_if_handshake(nc); DBG(("%p %d res %d", nc, server_side, res)); if (res == MG_SSL_OK) { nc->flags |= MG_F_SSL_HANDSHAKE_DONE; nc->flags &= ~(MG_F_WANT_READ | MG_F_WANT_WRITE); if (server_side) { union socket_address sa; socklen_t sa_len = sizeof(sa); (void) getpeername(nc->sock, &sa.sa, &sa_len); mg_if_accept_tcp_cb(nc, &sa, sa_len); } else { mg_if_connect_cb(nc, 0); } } else if (res != MG_SSL_WANT_READ && res != MG_SSL_WANT_WRITE) { if (!server_side) { mg_if_connect_cb(nc, res); } nc->flags |= MG_F_CLOSE_IMMEDIATELY; } }