vtls: move common early data code into vtls.c
With now 2 backends implementing early data, it makes sense to have the common handling in a single place. Closes #16450
This commit is contained in:
parent
a1d00da81e
commit
4ed9db9eef
129
lib/vtls/gtls.c
129
lib/vtls/gtls.c
@ -1064,7 +1064,7 @@ static CURLcode gtls_on_session_reuse(struct Curl_cfilter *cf,
|
||||
else {
|
||||
infof(data, "SSL session allows %zu bytes of early data, "
|
||||
"reusing ALPN '%s'", connssl->earlydata_max, scs->alpn);
|
||||
connssl->earlydata_state = ssl_earlydata_use;
|
||||
connssl->earlydata_state = ssl_earlydata_await;
|
||||
connssl->state = ssl_connection_deferred;
|
||||
result = Curl_alpn_set_negotiated(cf, data, connssl,
|
||||
(const unsigned char *)scs->alpn,
|
||||
@ -1756,30 +1756,6 @@ out:
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode gtls_set_earlydata(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
const void *buf, size_t blen)
|
||||
{
|
||||
struct ssl_connect_data *connssl = cf->ctx;
|
||||
ssize_t nwritten = 0;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
DEBUGASSERT(connssl->earlydata_state == ssl_earlydata_use);
|
||||
DEBUGASSERT(Curl_bufq_is_empty(&connssl->earlydata));
|
||||
if(blen) {
|
||||
if(blen > connssl->earlydata_max)
|
||||
blen = connssl->earlydata_max;
|
||||
nwritten = Curl_bufq_write(&connssl->earlydata, buf, blen, &result);
|
||||
CURL_TRC_CF(data, cf, "gtls_set_earlydata(len=%zu) -> %zd",
|
||||
blen, nwritten);
|
||||
if(nwritten < 0)
|
||||
return result;
|
||||
}
|
||||
connssl->earlydata_state = ssl_earlydata_sending;
|
||||
connssl->earlydata_skip = Curl_bufq_len(&connssl->earlydata);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode gtls_send_earlydata(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
@ -1855,7 +1831,7 @@ static CURLcode gtls_connect_common(struct Curl_cfilter *cf,
|
||||
}
|
||||
|
||||
if(connssl->connecting_state == ssl_connect_2) {
|
||||
if(connssl->earlydata_state == ssl_earlydata_use) {
|
||||
if(connssl->earlydata_state == ssl_earlydata_await) {
|
||||
goto out;
|
||||
}
|
||||
else if(connssl->earlydata_state == ssl_earlydata_sending) {
|
||||
@ -1863,8 +1839,6 @@ static CURLcode gtls_connect_common(struct Curl_cfilter *cf,
|
||||
if(result)
|
||||
goto out;
|
||||
connssl->earlydata_state = ssl_earlydata_sent;
|
||||
if(!Curl_ssl_cf_is_proxy(cf))
|
||||
Curl_pgrsEarlyData(data, (curl_off_t)connssl->earlydata_skip);
|
||||
}
|
||||
DEBUGASSERT((connssl->earlydata_state == ssl_earlydata_none) ||
|
||||
(connssl->earlydata_state == ssl_earlydata_sent));
|
||||
@ -1896,31 +1870,19 @@ static CURLcode gtls_connect_common(struct Curl_cfilter *cf,
|
||||
if(result)
|
||||
goto out;
|
||||
|
||||
if(connssl->earlydata_state == ssl_earlydata_sent) {
|
||||
/* report the true time the handshake was done */
|
||||
connssl->handshake_done = Curl_now();
|
||||
Curl_pgrsTimeWas(data, TIMER_APPCONNECT, connssl->handshake_done);
|
||||
if(gnutls_session_get_flags(backend->gtls.session) &
|
||||
GNUTLS_SFLAGS_EARLY_DATA) {
|
||||
connssl->earlydata_state = ssl_earlydata_accepted;
|
||||
infof(data, "Server accepted %zu bytes of TLS early data.",
|
||||
connssl->earlydata_skip);
|
||||
}
|
||||
else {
|
||||
connssl->earlydata_state = ssl_earlydata_rejected;
|
||||
if(!Curl_ssl_cf_is_proxy(cf))
|
||||
Curl_pgrsEarlyData(data, -(curl_off_t)connssl->earlydata_skip);
|
||||
infof(data, "Server rejected TLS early data.");
|
||||
connssl->earlydata_skip = 0;
|
||||
}
|
||||
if(connssl->earlydata_state > ssl_earlydata_none) {
|
||||
/* We should be in this state by now */
|
||||
DEBUGASSERT(connssl->earlydata_state == ssl_earlydata_sent);
|
||||
connssl->earlydata_state =
|
||||
(gnutls_session_get_flags(backend->gtls.session) &
|
||||
GNUTLS_SFLAGS_EARLY_DATA) ?
|
||||
ssl_earlydata_accepted : ssl_earlydata_rejected;
|
||||
}
|
||||
connssl->connecting_state = ssl_connect_done;
|
||||
}
|
||||
|
||||
if(ssl_connect_done == connssl->connecting_state) {
|
||||
connssl->state = ssl_connection_complete;
|
||||
*done = TRUE;
|
||||
}
|
||||
if(connssl->connecting_state == ssl_connect_done)
|
||||
DEBUGASSERT(connssl->state == ssl_connection_complete);
|
||||
|
||||
out:
|
||||
if(result == CURLE_AGAIN) {
|
||||
@ -1938,7 +1900,8 @@ static CURLcode gtls_connect(struct Curl_cfilter *cf,
|
||||
bool *done)
|
||||
{
|
||||
struct ssl_connect_data *connssl = cf->ctx;
|
||||
if(connssl->state == ssl_connection_deferred) {
|
||||
if((connssl->state == ssl_connection_deferred) &&
|
||||
(connssl->earlydata_state == ssl_earlydata_await)) {
|
||||
/* We refuse to be pushed, we are waiting for someone to send/recv. */
|
||||
*done = TRUE;
|
||||
return CURLE_OK;
|
||||
@ -1946,26 +1909,6 @@ static CURLcode gtls_connect(struct Curl_cfilter *cf,
|
||||
return gtls_connect_common(cf, data, done);
|
||||
}
|
||||
|
||||
static CURLcode gtls_connect_deferred(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
const void *buf,
|
||||
size_t blen,
|
||||
bool *done)
|
||||
{
|
||||
struct ssl_connect_data *connssl = cf->ctx;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
DEBUGASSERT(connssl->state == ssl_connection_deferred);
|
||||
*done = FALSE;
|
||||
if(connssl->earlydata_state == ssl_earlydata_use) {
|
||||
result = gtls_set_earlydata(cf, data, buf, blen);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
return gtls_connect_common(cf, data, done);
|
||||
}
|
||||
|
||||
static bool gtls_data_pending(struct Curl_cfilter *cf,
|
||||
const struct Curl_easy *data)
|
||||
{
|
||||
@ -1993,38 +1936,9 @@ static ssize_t gtls_send(struct Curl_cfilter *cf,
|
||||
ssize_t rc;
|
||||
size_t nwritten, total_written = 0;
|
||||
|
||||
(void)data;
|
||||
DEBUGASSERT(backend);
|
||||
|
||||
if(connssl->state == ssl_connection_deferred) {
|
||||
bool done = FALSE;
|
||||
*curlcode = gtls_connect_deferred(cf, data, buf, blen, &done);
|
||||
if(*curlcode) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
else if(!done) {
|
||||
*curlcode = CURLE_AGAIN;
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
DEBUGASSERT(connssl->state == ssl_connection_complete);
|
||||
}
|
||||
|
||||
if(connssl->earlydata_skip) {
|
||||
if(connssl->earlydata_skip >= blen) {
|
||||
connssl->earlydata_skip -= blen;
|
||||
*curlcode = CURLE_OK;
|
||||
rc = (ssize_t)blen;
|
||||
goto out;
|
||||
}
|
||||
else {
|
||||
total_written += connssl->earlydata_skip;
|
||||
buf = ((const char *)buf) + connssl->earlydata_skip;
|
||||
blen -= connssl->earlydata_skip;
|
||||
connssl->earlydata_skip = 0;
|
||||
}
|
||||
}
|
||||
|
||||
while(blen) {
|
||||
backend->gtls.io_result = CURLE_OK;
|
||||
rc = gnutls_record_send(backend->gtls.session, buf, blen);
|
||||
@ -2171,21 +2085,6 @@ static ssize_t gtls_recv(struct Curl_cfilter *cf,
|
||||
(void)data;
|
||||
DEBUGASSERT(backend);
|
||||
|
||||
if(connssl->state == ssl_connection_deferred) {
|
||||
bool done = FALSE;
|
||||
*curlcode = gtls_connect_deferred(cf, data, NULL, 0, &done);
|
||||
if(*curlcode) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
else if(!done) {
|
||||
*curlcode = CURLE_AGAIN;
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
DEBUGASSERT(connssl->state == ssl_connection_complete);
|
||||
}
|
||||
|
||||
ret = gnutls_record_recv(backend->gtls.session, buf, buffersize);
|
||||
if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
|
||||
*curlcode = CURLE_AGAIN;
|
||||
|
||||
166
lib/vtls/vtls.c
166
lib/vtls/vtls.c
@ -485,18 +485,6 @@ static void cf_ctx_free(struct ssl_connect_data *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
static CURLcode
|
||||
ssl_connect(struct Curl_cfilter *cf, struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct ssl_connect_data *connssl = cf->ctx;
|
||||
|
||||
if(!ssl_prefs_check(data))
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
|
||||
/* mark this is being ssl requested from here on. */
|
||||
return connssl->ssl_impl->do_connect(cf, data, done);
|
||||
}
|
||||
|
||||
CURLcode Curl_ssl_get_channel_binding(struct Curl_easy *data, int sockindex,
|
||||
struct dynbuf *binding)
|
||||
{
|
||||
@ -1318,7 +1306,7 @@ static CURLcode ssl_cf_connect(struct Curl_cfilter *cf,
|
||||
struct cf_call_data save;
|
||||
CURLcode result;
|
||||
|
||||
if(cf->connected) {
|
||||
if(cf->connected && (connssl->state != ssl_connection_deferred)) {
|
||||
*done = TRUE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
@ -1336,8 +1324,6 @@ static CURLcode ssl_cf_connect(struct Curl_cfilter *cf,
|
||||
|
||||
CF_DATA_SAVE(save, cf, data);
|
||||
CURL_TRC_CF(data, cf, "cf_connect()");
|
||||
DEBUGASSERT(data->conn);
|
||||
DEBUGASSERT(data->conn == cf->conn);
|
||||
DEBUGASSERT(connssl);
|
||||
|
||||
*done = FALSE;
|
||||
@ -1349,7 +1335,13 @@ static CURLcode ssl_cf_connect(struct Curl_cfilter *cf,
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = ssl_connect(cf, data, done);
|
||||
if(!connssl->prefs_checked) {
|
||||
if(!ssl_prefs_check(data))
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
connssl->prefs_checked = TRUE;
|
||||
}
|
||||
|
||||
result = connssl->ssl_impl->do_connect(cf, data, done);
|
||||
|
||||
if(!result && *done) {
|
||||
cf->connected = TRUE;
|
||||
@ -1358,6 +1350,8 @@ static CURLcode ssl_cf_connect(struct Curl_cfilter *cf,
|
||||
/* Connection can be deferred when sending early data */
|
||||
DEBUGASSERT(connssl->state == ssl_connection_complete ||
|
||||
connssl->state == ssl_connection_deferred);
|
||||
DEBUGASSERT(connssl->state != ssl_connection_deferred ||
|
||||
connssl->earlydata_state > ssl_earlydata_none);
|
||||
}
|
||||
out:
|
||||
CURL_TRC_CF(data, cf, "cf_connect() -> %d, done=%d", result, *done);
|
||||
@ -1365,6 +1359,77 @@ out:
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode ssl_cf_set_earlydata(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
const void *buf, size_t blen)
|
||||
{
|
||||
struct ssl_connect_data *connssl = cf->ctx;
|
||||
ssize_t nwritten = 0;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
DEBUGASSERT(connssl->earlydata_state == ssl_earlydata_await);
|
||||
DEBUGASSERT(Curl_bufq_is_empty(&connssl->earlydata));
|
||||
if(blen) {
|
||||
if(blen > connssl->earlydata_max)
|
||||
blen = connssl->earlydata_max;
|
||||
nwritten = Curl_bufq_write(&connssl->earlydata, buf, blen, &result);
|
||||
CURL_TRC_CF(data, cf, "ssl_cf_set_earlydata(len=%zu) -> %zd",
|
||||
blen, nwritten);
|
||||
if(nwritten < 0)
|
||||
return result;
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode ssl_cf_connect_deferred(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
const void *buf, size_t blen,
|
||||
bool *done)
|
||||
{
|
||||
struct ssl_connect_data *connssl = cf->ctx;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
DEBUGASSERT(connssl->state == ssl_connection_deferred);
|
||||
*done = FALSE;
|
||||
if(connssl->earlydata_state == ssl_earlydata_await) {
|
||||
result = ssl_cf_set_earlydata(cf, data, buf, blen);
|
||||
if(result)
|
||||
return result;
|
||||
/* we buffered any early data we'd like to send. Actually
|
||||
* do the connect now which sends it and performs the handshake. */
|
||||
connssl->earlydata_state = ssl_earlydata_sending;
|
||||
connssl->earlydata_skip = Curl_bufq_len(&connssl->earlydata);
|
||||
}
|
||||
|
||||
result = ssl_cf_connect(cf, data, done);
|
||||
|
||||
if(!result && *done) {
|
||||
Curl_pgrsTimeWas(data, TIMER_APPCONNECT, connssl->handshake_done);
|
||||
switch(connssl->earlydata_state) {
|
||||
case ssl_earlydata_none:
|
||||
break;
|
||||
case ssl_earlydata_accepted:
|
||||
if(!Curl_ssl_cf_is_proxy(cf))
|
||||
Curl_pgrsEarlyData(data, (curl_off_t)connssl->earlydata_skip);
|
||||
infof(data, "Server accepted %zu bytes of TLS early data.",
|
||||
connssl->earlydata_skip);
|
||||
break;
|
||||
case ssl_earlydata_rejected:
|
||||
if(!Curl_ssl_cf_is_proxy(cf))
|
||||
Curl_pgrsEarlyData(data, -(curl_off_t)connssl->earlydata_skip);
|
||||
infof(data, "Server rejected TLS early data.");
|
||||
connssl->earlydata_skip = 0;
|
||||
break;
|
||||
default:
|
||||
/* This should not happen. Either we do not use early data or we
|
||||
* should know if it was accepted or not. */
|
||||
DEBUGASSERT(NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool ssl_cf_data_pending(struct Curl_cfilter *cf,
|
||||
const struct Curl_easy *data)
|
||||
{
|
||||
@ -1383,21 +1448,57 @@ static bool ssl_cf_data_pending(struct Curl_cfilter *cf,
|
||||
}
|
||||
|
||||
static ssize_t ssl_cf_send(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data, const void *buf, size_t len,
|
||||
struct Curl_easy *data,
|
||||
const void *buf, size_t blen,
|
||||
bool eos, CURLcode *err)
|
||||
{
|
||||
struct ssl_connect_data *connssl = cf->ctx;
|
||||
struct cf_call_data save;
|
||||
ssize_t nwritten = 0;
|
||||
ssize_t nwritten = 0, early_written = 0;
|
||||
|
||||
(void)eos;
|
||||
/* OpenSSL and maybe other TLS libs do not like 0-length writes. Skip. */
|
||||
*err = CURLE_OK;
|
||||
if(len > 0) {
|
||||
CF_DATA_SAVE(save, cf, data);
|
||||
nwritten = connssl->ssl_impl->send_plain(cf, data, buf, len, err);
|
||||
CF_DATA_RESTORE(cf, save);
|
||||
|
||||
if(connssl->state == ssl_connection_deferred) {
|
||||
bool done = FALSE;
|
||||
*err = ssl_cf_connect_deferred(cf, data, buf, blen, &done);
|
||||
if(*err) {
|
||||
nwritten = -1;
|
||||
goto out;
|
||||
}
|
||||
else if(!done) {
|
||||
*err = CURLE_AGAIN;
|
||||
nwritten = -1;
|
||||
goto out;
|
||||
}
|
||||
DEBUGASSERT(connssl->state == ssl_connection_complete);
|
||||
}
|
||||
|
||||
if(connssl->earlydata_skip) {
|
||||
if(connssl->earlydata_skip >= blen) {
|
||||
connssl->earlydata_skip -= blen;
|
||||
*err = CURLE_OK;
|
||||
nwritten = (ssize_t)blen;
|
||||
goto out;
|
||||
}
|
||||
else {
|
||||
early_written = connssl->earlydata_skip;
|
||||
buf = ((const char *)buf) + connssl->earlydata_skip;
|
||||
blen -= connssl->earlydata_skip;
|
||||
connssl->earlydata_skip = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* OpenSSL and maybe other TLS libs do not like 0-length writes. Skip. */
|
||||
if(blen > 0)
|
||||
nwritten = connssl->ssl_impl->send_plain(cf, data, buf, blen, err);
|
||||
|
||||
if(nwritten >= 0)
|
||||
nwritten += early_written;
|
||||
|
||||
out:
|
||||
CF_DATA_RESTORE(cf, save);
|
||||
return nwritten;
|
||||
}
|
||||
|
||||
@ -1411,6 +1512,21 @@ static ssize_t ssl_cf_recv(struct Curl_cfilter *cf,
|
||||
|
||||
CF_DATA_SAVE(save, cf, data);
|
||||
*err = CURLE_OK;
|
||||
if(connssl->state == ssl_connection_deferred) {
|
||||
bool done = FALSE;
|
||||
*err = ssl_cf_connect_deferred(cf, data, NULL, 0, &done);
|
||||
if(*err) {
|
||||
nread = -1;
|
||||
goto out;
|
||||
}
|
||||
else if(!done) {
|
||||
*err = CURLE_AGAIN;
|
||||
nread = -1;
|
||||
goto out;
|
||||
}
|
||||
DEBUGASSERT(connssl->state == ssl_connection_complete);
|
||||
}
|
||||
|
||||
nread = connssl->ssl_impl->recv_plain(cf, data, buf, len, err);
|
||||
if(nread > 0) {
|
||||
DEBUGASSERT((size_t)nread <= len);
|
||||
@ -1419,6 +1535,8 @@ static ssize_t ssl_cf_recv(struct Curl_cfilter *cf,
|
||||
/* eof */
|
||||
*err = CURLE_OK;
|
||||
}
|
||||
|
||||
out:
|
||||
CURL_TRC_CF(data, cf, "cf_recv(len=%zu) -> %zd, %d", len,
|
||||
nread, *err);
|
||||
CF_DATA_RESTORE(cf, save);
|
||||
@ -1433,7 +1551,9 @@ static CURLcode ssl_cf_shutdown(struct Curl_cfilter *cf,
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
*done = TRUE;
|
||||
if(!cf->shutdown && Curl_ssl->shut_down) {
|
||||
/* If we have done the SSL handshake, shut down the connection cleanly */
|
||||
if(cf->connected && (connssl->state == ssl_connection_complete) &&
|
||||
!cf->shutdown && Curl_ssl->shut_down) {
|
||||
struct cf_call_data save;
|
||||
|
||||
CF_DATA_SAVE(save, cf, data);
|
||||
|
||||
@ -91,7 +91,7 @@ typedef enum {
|
||||
|
||||
typedef enum {
|
||||
ssl_earlydata_none,
|
||||
ssl_earlydata_use,
|
||||
ssl_earlydata_await,
|
||||
ssl_earlydata_sending,
|
||||
ssl_earlydata_sent,
|
||||
ssl_earlydata_accepted,
|
||||
@ -126,6 +126,7 @@ struct ssl_connect_data {
|
||||
int io_need; /* TLS signals special SEND/RECV needs */
|
||||
BIT(use_alpn); /* if ALPN shall be used in handshake */
|
||||
BIT(peer_closed); /* peer has closed connection */
|
||||
BIT(prefs_checked); /* SSL preferences have been checked */
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -525,7 +525,7 @@ static CURLcode wssl_on_session_reuse(struct Curl_cfilter *cf,
|
||||
else {
|
||||
infof(data, "SSL session allows %zu bytes of early data, "
|
||||
"reusing ALPN '%s'", connssl->earlydata_max, scs->alpn);
|
||||
connssl->earlydata_state = ssl_earlydata_use;
|
||||
connssl->earlydata_state = ssl_earlydata_await;
|
||||
connssl->state = ssl_connection_deferred;
|
||||
result = Curl_alpn_set_negotiated(cf, data, connssl,
|
||||
(const unsigned char *)scs->alpn,
|
||||
@ -1662,6 +1662,8 @@ static CURLcode wssl_handshake(struct Curl_cfilter *cf,
|
||||
}
|
||||
DEBUGASSERT((connssl->earlydata_state == ssl_earlydata_none) ||
|
||||
(connssl->earlydata_state == ssl_earlydata_sent));
|
||||
#else
|
||||
DEBUGASSERT(connssl->earlydata_state == ssl_earlydata_none);
|
||||
#endif /* WOLFSSL_EARLY_DATA */
|
||||
|
||||
wolfSSL_ERR_clear_error();
|
||||
@ -1788,52 +1790,6 @@ static CURLcode wssl_handshake(struct Curl_cfilter *cf,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
static CURLcode wssl_set_earlydata(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
const void *buf, size_t blen)
|
||||
{
|
||||
struct ssl_connect_data *connssl = cf->ctx;
|
||||
ssize_t nwritten = 0;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
DEBUGASSERT(connssl->earlydata_state == ssl_earlydata_use);
|
||||
DEBUGASSERT(Curl_bufq_is_empty(&connssl->earlydata));
|
||||
if(blen) {
|
||||
if(blen > connssl->earlydata_max)
|
||||
blen = connssl->earlydata_max;
|
||||
nwritten = Curl_bufq_write(&connssl->earlydata, buf, blen, &result);
|
||||
CURL_TRC_CF(data, cf, "wssl_set_earlydata(len=%zu) -> %zd",
|
||||
blen, nwritten);
|
||||
if(nwritten < 0)
|
||||
return result;
|
||||
}
|
||||
connssl->earlydata_state = ssl_earlydata_sending;
|
||||
connssl->earlydata_skip = Curl_bufq_len(&connssl->earlydata);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode wssl_connect_deferred(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
const void *buf,
|
||||
size_t blen,
|
||||
bool *done)
|
||||
{
|
||||
struct ssl_connect_data *connssl = cf->ctx;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
DEBUGASSERT(connssl->state == ssl_connection_deferred);
|
||||
*done = FALSE;
|
||||
if(connssl->earlydata_state == ssl_earlydata_use) {
|
||||
result = wssl_set_earlydata(cf, data, buf, blen);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
return wssl_connect(cf, data, done);
|
||||
}
|
||||
#endif /* WOLFSSL_EARLY_DATA */
|
||||
|
||||
static ssize_t wssl_send(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
const void *buf, size_t blen,
|
||||
@ -1847,38 +1803,6 @@ static ssize_t wssl_send(struct Curl_cfilter *cf,
|
||||
|
||||
wolfSSL_ERR_clear_error();
|
||||
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
if(connssl->state == ssl_connection_deferred) {
|
||||
bool done = FALSE;
|
||||
*curlcode = wssl_connect_deferred(cf, data, buf, blen, &done);
|
||||
if(*curlcode) {
|
||||
nwritten = -1;
|
||||
goto out;
|
||||
}
|
||||
else if(!done) {
|
||||
*curlcode = CURLE_AGAIN;
|
||||
nwritten = -1;
|
||||
goto out;
|
||||
}
|
||||
DEBUGASSERT(connssl->state == ssl_connection_complete);
|
||||
}
|
||||
|
||||
if(connssl->earlydata_skip) {
|
||||
if(connssl->earlydata_skip >= blen) {
|
||||
connssl->earlydata_skip -= blen;
|
||||
*curlcode = CURLE_OK;
|
||||
nwritten = (ssize_t)blen;
|
||||
goto out;
|
||||
}
|
||||
else {
|
||||
total_written += connssl->earlydata_skip;
|
||||
buf = ((const char *)buf) + connssl->earlydata_skip;
|
||||
blen -= connssl->earlydata_skip;
|
||||
connssl->earlydata_skip = 0;
|
||||
}
|
||||
}
|
||||
#endif /* WOLFSSL_EARLY_DATA */
|
||||
|
||||
if(blen) {
|
||||
int memlen = (blen > (size_t)INT_MAX) ? INT_MAX : (int)blen;
|
||||
int rc;
|
||||
@ -2071,21 +1995,6 @@ static ssize_t wssl_recv(struct Curl_cfilter *cf,
|
||||
|
||||
DEBUGASSERT(wssl);
|
||||
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
if(connssl->state == ssl_connection_deferred) {
|
||||
bool done = FALSE;
|
||||
*curlcode = wssl_connect_deferred(cf, data, NULL, 0, &done);
|
||||
if(*curlcode) {
|
||||
return -1;
|
||||
}
|
||||
else if(!done) {
|
||||
*curlcode = CURLE_AGAIN;
|
||||
return-1;
|
||||
}
|
||||
DEBUGASSERT(connssl->state == ssl_connection_complete);
|
||||
}
|
||||
#endif
|
||||
|
||||
wolfSSL_ERR_clear_error();
|
||||
*curlcode = CURLE_OK;
|
||||
|
||||
@ -2212,7 +2121,7 @@ static CURLcode wssl_connect(struct Curl_cfilter *cf,
|
||||
}
|
||||
|
||||
if(ssl_connect_2 == connssl->connecting_state) {
|
||||
if(connssl->earlydata_state == ssl_earlydata_use) {
|
||||
if(connssl->earlydata_state == ssl_earlydata_await) {
|
||||
/* We defer the handshake until request data arrives. */
|
||||
DEBUGASSERT(connssl->state == ssl_connection_deferred);
|
||||
goto out;
|
||||
@ -2272,23 +2181,13 @@ static CURLcode wssl_connect(struct Curl_cfilter *cf,
|
||||
connssl->state = ssl_connection_complete;
|
||||
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
if(connssl->earlydata_state == ssl_earlydata_sent) {
|
||||
/* report the true time the handshake was done */
|
||||
connssl->handshake_done = Curl_now();
|
||||
Curl_pgrsTimeWas(data, TIMER_APPCONNECT, connssl->handshake_done);
|
||||
if(wolfSSL_get_early_data_status(wssl->ssl) ==
|
||||
WOLFSSL_EARLY_DATA_REJECTED) {
|
||||
connssl->earlydata_state = ssl_earlydata_rejected;
|
||||
if(!Curl_ssl_cf_is_proxy(cf))
|
||||
Curl_pgrsEarlyData(data, -(curl_off_t)connssl->earlydata_skip);
|
||||
infof(data, "Server rejected TLS early data.");
|
||||
connssl->earlydata_skip = 0;
|
||||
}
|
||||
else if(connssl->earlydata_skip) {
|
||||
connssl->earlydata_state = ssl_earlydata_accepted;
|
||||
infof(data, "Server accepted %zu bytes of TLS early data.",
|
||||
connssl->earlydata_skip);
|
||||
}
|
||||
if(connssl->earlydata_state > ssl_earlydata_none) {
|
||||
/* We should be in this state by now */
|
||||
DEBUGASSERT(connssl->earlydata_state == ssl_earlydata_sent);
|
||||
connssl->earlydata_state =
|
||||
(wolfSSL_get_early_data_status(wssl->ssl) ==
|
||||
WOLFSSL_EARLY_DATA_REJECTED) ?
|
||||
ssl_earlydata_rejected : ssl_earlydata_accepted;
|
||||
}
|
||||
#endif /* WOLFSSL_EARLY_DATA */
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user