Skip to content

Commit cc87322

Browse files
Merge pull request #1999 from alfred-bratterud/v0.13.x
V0.13.x merged as it builds on vaskemaskin
2 parents 461343d + 39a3790 commit cc87322

50 files changed

Lines changed: 1893 additions & 597 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

api/net/botan/tls_server.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,18 @@ class Server : public Botan::TLS::Callbacks, public net::Stream
5555
m_transport->on_read(bs, {this, &Server::tls_read});
5656
this->m_on_read = cb;
5757
}
58+
void on_data(DataCallback cb) override {
59+
// FIXME
60+
throw std::runtime_error("on_data not implemented on botan::server");
61+
}
62+
size_t next_size() override {
63+
// FIXME
64+
throw std::runtime_error("next_size not implemented on botan::server");
65+
}
66+
buffer_t read_next() override {
67+
// FIXME
68+
throw std::runtime_error("read_next not implemented on botan::server");
69+
}
5870
void on_write(WriteCallback cb) override {
5971
this->m_on_write = cb;
6072
}

api/net/openssl/tls_stream.hpp

Lines changed: 10 additions & 278 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@
22
#include <openssl/err.h>
33
#include <openssl/pem.h>
44
#include <openssl/ssl.h>
5-
#include <net/stream.hpp>
5+
#include <net/stream_buffer.hpp>
66

7-
//#define VERBOSE_OPENSSL
7+
//#define VERBOSE_OPENSSL 0
88
#ifdef VERBOSE_OPENSSL
9-
#define TLS_PRINT(fmt, ...) printf(fmt, ##__VA_ARGS__)
9+
#define TLS_PRINT(fmt, ...) printf("TLS_Stream");printf(fmt, ##__VA_ARGS__)
1010
#else
1111
#define TLS_PRINT(fmt, ...) /* fmt */
1212
#endif
1313

1414
namespace openssl
1515
{
16-
struct TLS_stream : public net::Stream
16+
struct TLS_stream : public net::StreamBuffer
1717
{
1818
using Stream_ptr = net::Stream_ptr;
1919

@@ -25,7 +25,6 @@ namespace openssl
2525
void write(const std::string&) override;
2626
void write(const void* buf, size_t n) override;
2727
void close() override;
28-
void reset_callbacks() override;
2928

3029
net::Socket local() const override {
3130
return m_transport->local();
@@ -37,24 +36,11 @@ namespace openssl
3736
return m_transport->to_string();
3837
}
3938

40-
void on_connect(ConnectCallback cb) override {
41-
m_on_connect = std::move(cb);
42-
}
43-
void on_read(size_t, ReadCallback cb) override {
44-
m_on_read = std::move(cb);
45-
}
46-
void on_close(CloseCallback cb) override {
47-
m_on_close = std::move(cb);
48-
}
49-
void on_write(WriteCallback cb) override {
50-
m_on_write = std::move(cb);
51-
}
52-
5339
bool is_connected() const noexcept override {
5440
return handshake_completed() && m_transport->is_connected();
5541
}
5642
bool is_writable() const noexcept override {
57-
return is_connected() && m_transport->is_writable();
43+
return (not write_congested()) && is_connected() && m_transport->is_writable();
5844
}
5945
bool is_readable() const noexcept override {
6046
return m_transport->is_readable();
@@ -76,7 +62,12 @@ namespace openssl
7662

7763
size_t serialize_to(void*) const override;
7864

65+
void handle_read_congestion() override;
66+
void handle_write_congestion() override;
7967
private:
68+
void handle_data();
69+
int decrypt(const void *data,int size);
70+
int send_decrypted();
8071
void tls_read(buffer_t);
8172
int tls_perform_stream_write();
8273
int tls_perform_handshake();
@@ -89,271 +80,12 @@ namespace openssl
8980
STATUS_FAIL
9081
};
9182
status_t status(int n) const noexcept;
92-
9383
Stream_ptr m_transport = nullptr;
9484
SSL* m_ssl = nullptr;
9585
BIO* m_bio_rd = nullptr;
9686
BIO* m_bio_wr = nullptr;
9787
bool m_busy = false;
9888
bool m_deferred_close = false;
99-
ConnectCallback m_on_connect = nullptr;
100-
ReadCallback m_on_read = nullptr;
101-
WriteCallback m_on_write = nullptr;
102-
CloseCallback m_on_close = nullptr;
10389
};
10490

105-
inline TLS_stream::TLS_stream(SSL_CTX* ctx, Stream_ptr t, bool outgoing)
106-
: m_transport(std::move(t))
107-
{
108-
ERR_clear_error(); // prevent old errors from mucking things up
109-
this->m_bio_rd = BIO_new(BIO_s_mem());
110-
this->m_bio_wr = BIO_new(BIO_s_mem());
111-
assert(ERR_get_error() == 0 && "Initializing BIOs");
112-
this->m_ssl = SSL_new(ctx);
113-
assert(this->m_ssl != nullptr);
114-
assert(ERR_get_error() == 0 && "Initializing SSL");
115-
// TLS server-mode
116-
if (outgoing == false)
117-
SSL_set_accept_state(this->m_ssl);
118-
else
119-
SSL_set_connect_state(this->m_ssl);
120-
121-
SSL_set_bio(this->m_ssl, this->m_bio_rd, this->m_bio_wr);
122-
// always-on callbacks
123-
m_transport->on_read(8192, {this, &TLS_stream::tls_read});
124-
m_transport->on_close({this, &TLS_stream::close_callback_once});
125-
126-
// start TLS handshake process
127-
if (outgoing == true)
128-
{
129-
if (this->tls_perform_handshake() < 0) return;
130-
}
131-
}
132-
inline TLS_stream::TLS_stream(Stream_ptr t, SSL* ssl, BIO* rd, BIO* wr)
133-
: m_transport(std::move(t)), m_ssl(ssl), m_bio_rd(rd), m_bio_wr(wr)
134-
{
135-
// always-on callbacks
136-
m_transport->on_read(8192, {this, &TLS_stream::tls_read});
137-
m_transport->on_close({this, &TLS_stream::close_callback_once});
138-
}
139-
inline TLS_stream::~TLS_stream()
140-
{
141-
assert(m_busy == false && "Cannot delete stream while in its call stack");
142-
SSL_free(this->m_ssl);
143-
}
144-
145-
inline void TLS_stream::write(buffer_t buffer)
146-
{
147-
if (UNLIKELY(this->is_connected() == false)) {
148-
TLS_PRINT("TLS_stream::write() called on closed stream\n");
149-
return;
150-
}
151-
152-
int n = SSL_write(this->m_ssl, buffer->data(), buffer->size());
153-
auto status = this->status(n);
154-
if (status == STATUS_FAIL) {
155-
this->close();
156-
return;
157-
}
158-
159-
do {
160-
n = tls_perform_stream_write();
161-
} while (n > 0);
162-
}
163-
inline void TLS_stream::write(const std::string& str)
164-
{
165-
write(net::Stream::construct_buffer(str.data(), str.data() + str.size()));
166-
}
167-
inline void TLS_stream::write(const void* data, const size_t len)
168-
{
169-
auto* buf = static_cast<const uint8_t*> (data);
170-
write(net::Stream::construct_buffer(buf, buf + len));
171-
}
172-
173-
inline void TLS_stream::tls_read(buffer_t buffer)
174-
{
175-
ERR_clear_error();
176-
uint8_t* buf = buffer->data();
177-
int len = buffer->size();
178-
179-
while (len > 0)
180-
{
181-
int n = BIO_write(this->m_bio_rd, buf, len);
182-
if (UNLIKELY(n < 0)) {
183-
this->close();
184-
return;
185-
}
186-
buf += n;
187-
len -= n;
188-
189-
// if we aren't finished initializing session
190-
if (UNLIKELY(!handshake_completed()))
191-
{
192-
int num = SSL_do_handshake(this->m_ssl);
193-
auto status = this->status(num);
194-
195-
// OpenSSL wants to write
196-
if (status == STATUS_WANT_IO)
197-
{
198-
tls_perform_stream_write();
199-
}
200-
else if (status == STATUS_FAIL)
201-
{
202-
if (num < 0) {
203-
TLS_PRINT("TLS_stream::SSL_do_handshake() returned %d\n", num);
204-
#ifdef VERBOSE_OPENSSL
205-
ERR_print_errors_fp(stdout);
206-
#endif
207-
}
208-
this->close();
209-
return;
210-
}
211-
// nothing more to do if still not finished
212-
if (handshake_completed() == false) return;
213-
// handshake success
214-
if (m_on_connect) m_on_connect(*this);
215-
}
216-
217-
// read decrypted data
218-
do {
219-
char temp[8192];
220-
n = SSL_read(this->m_ssl, temp, sizeof(temp));
221-
if (n > 0) {
222-
auto buf = net::Stream::construct_buffer(temp, temp + n);
223-
if (m_on_read) {
224-
this->m_busy = true;
225-
m_on_read(std::move(buf));
226-
this->m_busy = false;
227-
}
228-
}
229-
} while (n > 0);
230-
// this goes here?
231-
if (UNLIKELY(this->is_closing() || this->is_closed())) {
232-
TLS_PRINT("TLS_stream::SSL_read closed during read\n");
233-
return;
234-
}
235-
if (this->m_deferred_close) {
236-
this->close(); return;
237-
}
238-
239-
auto status = this->status(n);
240-
// did peer request stream renegotiation?
241-
if (status == STATUS_WANT_IO)
242-
{
243-
do {
244-
n = tls_perform_stream_write();
245-
} while (n > 0);
246-
}
247-
else if (status == STATUS_FAIL)
248-
{
249-
this->close();
250-
return;
251-
}
252-
// check deferred closing
253-
if (this->m_deferred_close) {
254-
this->close(); return;
255-
}
256-
257-
} // while it < end
258-
} // tls_read()
259-
260-
inline int TLS_stream::tls_perform_stream_write()
261-
{
262-
ERR_clear_error();
263-
int pending = BIO_ctrl_pending(this->m_bio_wr);
264-
//printf("pending: %d\n", pending);
265-
if (pending > 0)
266-
{
267-
auto buffer = net::Stream::construct_buffer(pending);
268-
int n = BIO_read(this->m_bio_wr, buffer->data(), buffer->size());
269-
assert(n == pending);
270-
m_transport->write(buffer);
271-
if (m_on_write) {
272-
this->m_busy = true;
273-
m_on_write(n);
274-
this->m_busy = false;
275-
}
276-
return n;
277-
}
278-
else {
279-
BIO_read(this->m_bio_wr, nullptr, 0);
280-
}
281-
if (!BIO_should_retry(this->m_bio_wr))
282-
{
283-
this->close();
284-
return -1;
285-
}
286-
return 0;
287-
}
288-
inline int TLS_stream::tls_perform_handshake()
289-
{
290-
ERR_clear_error(); // prevent old errors from mucking things up
291-
// will return -1:SSL_ERROR_WANT_WRITE
292-
int ret = SSL_do_handshake(this->m_ssl);
293-
int n = this->status(ret);
294-
ERR_print_errors_fp(stderr);
295-
if (n == STATUS_WANT_IO)
296-
{
297-
do {
298-
n = tls_perform_stream_write();
299-
if (n < 0) {
300-
TLS_PRINT("TLS_stream::tls_perform_handshake() stream write failed\n");
301-
}
302-
} while (n > 0);
303-
return n;
304-
}
305-
else {
306-
TLS_PRINT("TLS_stream::tls_perform_handshake() returned %d\n", ret);
307-
this->close();
308-
return -1;
309-
}
310-
}
311-
312-
inline void TLS_stream::close()
313-
{
314-
//ERR_clear_error();
315-
if (this->m_busy) {
316-
this->m_deferred_close = true; return;
317-
}
318-
CloseCallback func = std::move(this->m_on_close);
319-
this->reset_callbacks();
320-
if (m_transport->is_connected())
321-
m_transport->close();
322-
if (func) func();
323-
}
324-
inline void TLS_stream::close_callback_once()
325-
{
326-
if (this->m_busy) {
327-
this->m_deferred_close = true; return;
328-
}
329-
CloseCallback func = std::move(this->m_on_close);
330-
this->reset_callbacks();
331-
if (func) func();
332-
}
333-
inline void TLS_stream::reset_callbacks()
334-
{
335-
this->m_on_close = nullptr;
336-
this->m_on_connect = nullptr;
337-
this->m_on_read = nullptr;
338-
this->m_on_write = nullptr;
339-
}
340-
341-
inline bool TLS_stream::handshake_completed() const noexcept
342-
{
343-
return SSL_is_init_finished(this->m_ssl);
344-
}
345-
inline TLS_stream::status_t TLS_stream::status(int n) const noexcept
346-
{
347-
int error = SSL_get_error(this->m_ssl, n);
348-
switch (error)
349-
{
350-
case SSL_ERROR_NONE:
351-
return STATUS_OK;
352-
case SSL_ERROR_WANT_WRITE:
353-
case SSL_ERROR_WANT_READ:
354-
return STATUS_WANT_IO;
355-
default:
356-
return STATUS_FAIL;
357-
}
358-
}
35991
} // openssl

api/net/stream.hpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,32 @@ namespace net {
5656
/** Called with a shared buffer and the length of the data when received. */
5757
using ReadCallback = delegate<void(buffer_t)>;
5858
/**
59-
* @brief Event when data is received.
59+
* @brief Event when data is received. Pushes data to the callback.
6060
*
6161
* @param[in] n The size of the receive buffer
6262
* @param[in] cb The read callback
6363
*/
6464
virtual void on_read(size_t n, ReadCallback cb) = 0;
6565

66+
using DataCallback = delegate<void()>;
67+
/**
68+
* @brief Event when data is received.
69+
* Does not push data, just signals its presence.
70+
*
71+
* @param[in] cb The callback
72+
*/
73+
virtual void on_data(DataCallback cb) = 0;
74+
75+
/**
76+
* @return The size of the next available chunk of data if any.
77+
*/
78+
virtual size_t next_size() = 0;
79+
80+
/**
81+
* @return The next available chunk of data if any.
82+
*/
83+
virtual buffer_t read_next() = 0;
84+
6685
/** Called with nothing ¯\_(ツ)_/¯ */
6786
using CloseCallback = delegate<void()>;
6887
/**

0 commit comments

Comments
 (0)