mirror of https://github.com/getdnsapi/getdns.git
Replace SSL_write().
This commit is contained in:
parent
e7453522d5
commit
09019bee75
|
@ -404,6 +404,39 @@ getdns_return_t _getdns_tls_connection_read(_getdns_tls_connection* conn, uint8_
|
|||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t _getdns_tls_connection_write(_getdns_tls_connection* conn, uint8_t* buf, size_t to_write, size_t* written)
|
||||
{
|
||||
int swritten;
|
||||
|
||||
if (!conn || !conn->ssl || !written)
|
||||
return -GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
ERR_clear_error();
|
||||
swritten = SSL_write(conn->ssl, buf, to_write);
|
||||
if (swritten <= 0) {
|
||||
switch(SSL_get_error(conn->ssl, swritten)) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
/* SSL_write will not do partial writes, because
|
||||
* SSL_MODE_ENABLE_PARTIAL_WRITE is not default,
|
||||
* but the write could fail because of renegotiation.
|
||||
* In that case SSL_get_error() will return
|
||||
* SSL_ERROR_WANT_READ or, SSL_ERROR_WANT_WRITE.
|
||||
* Return for retry in such cases.
|
||||
*/
|
||||
return GETDNS_RETURN_TLS_WANT_READ;
|
||||
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
return GETDNS_RETURN_TLS_WANT_WRITE;
|
||||
|
||||
default:
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
*written = swritten;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t _getdns_tls_session_free(_getdns_tls_session* s)
|
||||
{
|
||||
if (!s || !s->ssl)
|
||||
|
|
|
@ -120,6 +120,21 @@ getdns_return_t _getdns_tls_connection_is_session_reused(_getdns_tls_connection*
|
|||
*/
|
||||
getdns_return_t _getdns_tls_connection_read(_getdns_tls_connection* conn, uint8_t* buf, size_t to_read, size_t* read);
|
||||
|
||||
/**
|
||||
* Write to TLS.
|
||||
*
|
||||
* @param conn the connection.
|
||||
* @param buf the buffer to write from.
|
||||
* @param to_write the number of bytes to write.
|
||||
* @param written the number of bytes written.
|
||||
* @return GETDNS_RETURN_GOOD if some bytes were read.
|
||||
* @return GETDNS_RETURN_INVALID_PARAMETER if conn is null or has no SSL.
|
||||
* @return GETDNS_RETURN_TLS_WANT_READ if handshake isn't finished.
|
||||
* @return GETDNS_RETURN_TLS_WANT_WRITE if the write needs to be retried.
|
||||
* @return GETDNS_RETURN_GENERIC_ERROR if write failed.
|
||||
*/
|
||||
getdns_return_t _getdns_tls_connection_write(_getdns_tls_connection* conn, uint8_t* buf, size_t to_write, size_t* written);
|
||||
|
||||
getdns_return_t _getdns_tls_session_free(_getdns_tls_session* s);
|
||||
|
||||
getdns_return_t _getdns_tls_get_api_information(getdns_dict* dict);
|
||||
|
|
25
src/stub.c
25
src/stub.c
|
@ -1359,10 +1359,10 @@ stub_tls_write(getdns_upstream *upstream, getdns_tcp_state *tcp,
|
|||
getdns_network_req *netreq)
|
||||
{
|
||||
size_t pkt_len;
|
||||
ssize_t written;
|
||||
size_t written;
|
||||
uint16_t query_id;
|
||||
intptr_t query_id_intptr;
|
||||
SSL* tls_obj = upstream->tls_obj->ssl;
|
||||
_getdns_tls_connection* tls_obj = upstream->tls_obj;
|
||||
uint16_t padding_sz;
|
||||
|
||||
int q = tls_connected(upstream);
|
||||
|
@ -1437,7 +1437,6 @@ stub_tls_write(getdns_upstream *upstream, getdns_tcp_state *tcp,
|
|||
* Lets see how much of it we can write */
|
||||
|
||||
/* TODO[TLS]: Handle error cases, partial writes, renegotiation etc. */
|
||||
ERR_clear_error();
|
||||
#if INTERCEPT_COM_DS
|
||||
/* Intercept and do not sent out COM DS queries. For debugging
|
||||
* purposes only. Never commit with this turned on.
|
||||
|
@ -1454,23 +1453,17 @@ stub_tls_write(getdns_upstream *upstream, getdns_tcp_state *tcp,
|
|||
written = pkt_len + 2;
|
||||
} else
|
||||
#endif
|
||||
written = SSL_write(tls_obj, netreq->query - 2, pkt_len + 2);
|
||||
if (written <= 0) {
|
||||
/* SSL_write will not do partial writes, because
|
||||
* SSL_MODE_ENABLE_PARTIAL_WRITE is not default,
|
||||
* but the write could fail because of renegotiation.
|
||||
* In that case SSL_get_error() will return
|
||||
* SSL_ERROR_WANT_READ or, SSL_ERROR_WANT_WRITE.
|
||||
* Return for retry in such cases.
|
||||
*/
|
||||
switch (SSL_get_error(tls_obj, written)) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
switch ((int)_getdns_tls_connection_write(tls_obj, netreq->query - 2, pkt_len + 2, &written)) {
|
||||
case GETDNS_RETURN_GOOD:
|
||||
break;
|
||||
|
||||
case GETDNS_RETURN_TLS_WANT_READ:
|
||||
case GETDNS_RETURN_TLS_WANT_WRITE:
|
||||
return STUB_TCP_RETRY;
|
||||
|
||||
default:
|
||||
return STUB_TCP_ERROR;
|
||||
}
|
||||
}
|
||||
/* We were able to write everything! Start reading. */
|
||||
return (int) query_id;
|
||||
|
||||
|
|
Loading…
Reference in New Issue