static bool recv_handler(int *err, struct mbuf *mb, bool *estab, void *arg) { struct tls_conn *tc = arg; int r; /* feed SSL data to the BIO */ r = BIO_write(tc->sbio_in, mbuf_buf(mb), (int)mbuf_get_left(mb)); if (r <= 0) { DEBUG_WARNING("recv: BIO_write %d\n", r); *err = ENOMEM; return true; } if (SSL_state(tc->ssl) != SSL_ST_OK) { if (tc->up) { *err = EPROTO; return true; } if (tc->active) { *err = tls_connect(tc); } else { *err = tls_accept(tc); } DEBUG_INFO("state=0x%04x\n", SSL_state(tc->ssl)); /* TLS connection is established */ if (SSL_state(tc->ssl) != SSL_ST_OK) return true; *estab = true; tc->up = true; } mbuf_set_pos(mb, 0); for (;;) { int n; if (mbuf_get_space(mb) < 4096) { *err = mbuf_resize(mb, mb->size + 8192); if (*err) return true; } n = SSL_read(tc->ssl, mbuf_buf(mb), (int)mbuf_get_space(mb)); if (n < 0) { const int ssl_err = SSL_get_error(tc->ssl, n); switch (ssl_err) { case SSL_ERROR_WANT_READ: break; default: *err = EPROTO; return true; } break; } else if (n == 0) break; mb->pos += n; } mbuf_set_end(mb, mb->pos); mbuf_set_pos(mb, 0); return false; }
static bool recv_handler(struct sa *src, struct mbuf *mb, void *arg) { struct tls_sock *ts = arg; struct tls_conn *tc; int r; tc = tls_udp_conn(ts, src); if (!tc) { /* No connection found, assuming Server role */ tc = conn_alloc(ts, src); if (!tc) return true; SSL_set_verify(tc->ssl, 0, 0); SSL_set_accept_state(tc->ssl); } /* feed SSL data to the BIO */ r = BIO_write(tc->sbio_in, mbuf_buf(mb), (int)mbuf_get_left(mb)); if (r <= 0) return true; check_timer(tc); mbuf_set_pos(mb, 0); for (;;) { int n; if (mbuf_get_space(mb) < 4096) { if (mbuf_resize(mb, mb->size + 8192)) return true; } n = SSL_read(tc->ssl, mbuf_buf(mb), (int)mbuf_get_space(mb)); if (n < 0) { const int ssl_err = SSL_get_error(tc->ssl, n); switch (ssl_err) { case SSL_ERROR_WANT_READ: break; default: return true; } break; } else if (n == 0) break; mb->pos += n; } if (!mb->pos) return true; mbuf_set_end(mb, mb->pos); mbuf_set_pos(mb, 0); return false; }