diff --git a/core/future.hh b/core/future.hh index 067b384c57..c716840234 100644 --- a/core/future.hh +++ b/core/future.hh @@ -341,6 +341,9 @@ private: friend class future; }; +template<> +class promise : public promise<> {}; + template struct is_future : std::false_type {}; template struct is_future> : std::true_type {}; diff --git a/core/xen/xenstore.hh b/core/xen/xenstore.hh index fe60682dea..a496a80c59 100644 --- a/core/xen/xenstore.hh +++ b/core/xen/xenstore.hh @@ -22,6 +22,8 @@ #ifndef XENSTORE_HH_ #define XENSTORE_HH_ +#include + extern "C" { #include } diff --git a/net/tcp.hh b/net/tcp.hh index 648846a0cc..188acb6d5b 100644 --- a/net/tcp.hh +++ b/net/tcp.hh @@ -915,8 +915,9 @@ void tcp::tcb::init_from_options(tcp_hdr* th, uint8_t* opt_start, ui template void tcp::tcb::input_handle_listen_state(tcp_hdr* th, packet p) { - auto opt_start = p.get_header(sizeof(tcp_hdr)); - auto opt_end = opt_start + th->data_offset * 4; + auto opt_len = th->data_offset * 4 - sizeof(tcp_hdr); + auto opt_start = reinterpret_cast(p.get_header(0, th->data_offset * 4)) + sizeof(tcp_hdr); + auto opt_end = opt_start + opt_len; p.trim_front(th->data_offset * 4); tcp_seq seg_seq = th->seq; @@ -943,8 +944,9 @@ void tcp::tcb::input_handle_listen_state(tcp_hdr* th, packet p) { template void tcp::tcb::input_handle_syn_sent_state(tcp_hdr* th, packet p) { - auto opt_start = p.get_header(sizeof(tcp_hdr)); - auto opt_end = opt_start + th->data_offset * 4; + auto opt_len = th->data_offset * 4 - sizeof(tcp_hdr); + auto opt_start = reinterpret_cast(p.get_header(0, th->data_offset * 4)) + sizeof(tcp_hdr); + auto opt_end = opt_start + opt_len; p.trim_front(th->data_offset * 4); tcp_seq seg_seq = th->seq; auto seg_ack = th->ack; diff --git a/net/virtio.cc b/net/virtio.cc index 0c09543948..72185fddd9 100644 --- a/net/virtio.cc +++ b/net/virtio.cc @@ -554,6 +554,7 @@ protected: private: future<> prepare_buffers(); void complete_buffer(single_buffer&& b, size_t len); + void debug_mode_adjust_fragments(); }; protected: device* _dev; @@ -666,6 +667,22 @@ qp::rxq::prepare_buffers() { }); } +void +qp::rxq::debug_mode_adjust_fragments() { +#ifdef DEBUG + // For debug mode, reallocate last fragment to detect buffer overruns + auto last = _fragments.back(); + auto sz = last.size; + std::unique_ptr buf(reinterpret_cast(malloc(sz))); + if (!buf) { + throw std::bad_alloc(); + } + std::copy_n(last.base, sz, buf.get()); + _fragments.back() = { buf.get(), sz }; + _buffers.back() = std::move(buf); +#endif +} + void qp::rxq::complete_buffer(single_buffer&& bc, size_t len) { auto&& sb = bc[0]; @@ -690,6 +707,7 @@ qp::rxq::complete_buffer(single_buffer&& bc, size_t len) { // Last buffer if (_remaining_buffers == 0) { + debug_mode_adjust_fragments(); deleter del; if (_buffers.size() == 1) { del = make_free_deleter(_buffers[0].release());