void mg_lwip_ssl_send(struct mg_connection *nc) { if (nc->sock == INVALID_SOCKET) { DBG(("%p invalid socket", nc)); return; } struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; /* It's ok if the buffer is empty. Return value of 0 may also be valid. */ int len = cs->last_ssl_write_size; if (len == 0) { len = MIN(MG_LWIP_SSL_IO_SIZE, nc->send_mbuf.len); } int ret = mg_ssl_if_write(nc, nc->send_mbuf.buf, len); DBG(("%p SSL_write %u = %d", nc, len, ret)); if (ret > 0) { mg_if_sent_cb(nc, ret); cs->last_ssl_write_size = 0; } else if (ret < 0) { /* This is tricky. We must remember the exact data we were sending to retry * exactly the same send next time. */ cs->last_ssl_write_size = len; } if (ret == len) { nc->flags &= ~MG_F_WANT_WRITE; } else if (ret == MG_SSL_WANT_WRITE) { nc->flags |= MG_F_WANT_WRITE; } else { mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc); } }
static void mg_write_to_socket(struct mg_connection *nc) { struct mbuf *io = &nc->send_mbuf; int n = 0; #if MG_LWIP /* With LWIP we don't know if the socket is ready */ if (io->len == 0) return; #endif assert(io->len > 0); if (nc->flags & MG_F_UDP) { int n = sendto(nc->sock, io->buf, io->len, 0, &nc->sa.sa, sizeof(nc->sa.sin)); DBG(("%p %d %d %d %s:%hu", nc, nc->sock, n, mg_get_errno(), inet_ntoa(nc->sa.sin.sin_addr), ntohs(nc->sa.sin.sin_port))); mg_if_sent_cb(nc, n); return; } #if MG_ENABLE_SSL if (nc->flags & MG_F_SSL) { if (nc->flags & MG_F_SSL_HANDSHAKE_DONE) { n = mg_ssl_if_write(nc, io->buf, io->len); DBG(("%p %d bytes -> %d (SSL)", nc, n, nc->sock)); if (n < 0) { if (n != MG_SSL_WANT_READ && n != MG_SSL_WANT_WRITE) { nc->flags |= MG_F_CLOSE_IMMEDIATELY; } return; } else { /* Successful SSL operation, clear off SSL wait flags */ nc->flags &= ~(MG_F_WANT_READ | MG_F_WANT_WRITE); } } else { mg_ssl_begin(nc); return; } } else #endif { n = (int) MG_SEND_FUNC(nc->sock, io->buf, io->len, 0); DBG(("%p %d bytes -> %d", nc, n, nc->sock)); } mg_if_sent_cb(nc, n); }