Skip to content

Commit

Permalink
tls: Fix tls sink::put so it deals with larger packets
Browse files Browse the repository at this point in the history
Lame bug: gnutls internal buffers limit data sent on each pass to
~16k, which code did not deal with, i.e. we did not check how
large part of data was actually transmitted.

Add secondary put loop to work us through the sub-packets.

Message-Id: <[email protected]>
  • Loading branch information
Calle Wilund authored and avikivity committed Apr 27, 2016
1 parent 1188c13 commit dab58e4
Showing 1 changed file with 23 additions and 23 deletions.
46 changes: 23 additions & 23 deletions net/tls.cc
Original file line number Diff line number Diff line change
Expand Up @@ -785,34 +785,34 @@ class session::sink_impl: public ::data_sink_impl {
private:
typedef net::fragment* frag_iter;

future<> put(net::packet p, frag_iter i, frag_iter e) {
future<> put(net::packet p, frag_iter i, frag_iter e, size_t off = 0) {
while (i != e) {
auto ptr = i->base;
auto size = i->size;
// gnutls does not have a sendv. Why?...
auto res = gnutls_record_send(_session, ptr, size);

++i;

if (res < 0) {
switch (res) {
case GNUTLS_E_AGAIN:
// See the session::put comments.
// If underlying says EAGAIN, we've actually issued
// a send, but must wait for completion.
return _session.wait_for_output().then(
[this, p = std::move(p), size, i, e]() mutable {
// re-send same buffers (gnutls internal)
auto check = gnutls_record_send(_session, nullptr, 0);
if (size_t(check) != size) {
throw std::logic_error("State machine broken?");
}
return this->put(std::move(p), i, e);
});
default:
return _session.handle_output_error(res);
while (off < size) {
// gnutls does not have a sendv. Why?...
auto res = gnutls_record_send(_session, ptr + off, size - off);

if (res < 0) {
switch (res) {
case GNUTLS_E_AGAIN:
// See the session::put comments.
// If underlying says EAGAIN, we've actually issued
// a send, but must wait for completion.
return _session.wait_for_output().then(
[this, p = std::move(p), size, i, e, off]() mutable {
// re-send same buffers (gnutls internal)
auto check = gnutls_record_send(_session, nullptr, 0);
return this->put(std::move(p), i, e, off + check);
});
default:
return _session.handle_output_error(res);
}
}
off += res;
}
off = 0;
++i;
}
return make_ready_future<>();
}
Expand Down

0 comments on commit dab58e4

Please sign in to comment.