Skip to content

Commit ac453cf

Browse files
committed
Merge branch 'tcp_rcvwnd' of github.com:AndreasAakesson/IncludeOS into lbfix
2 parents 974847c + 565afc7 commit ac453cf

4 files changed

Lines changed: 47 additions & 2 deletions

File tree

api/net/tcp/connection.hpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,8 @@ class Connection {
231231
SEQ_OUT_OF_ORDER,
232232
ACK_NOT_SET,
233233
ACK_OUT_OF_ORDER,
234-
RST
234+
RST,
235+
RCV_WND_ZERO
235236
}; // < Drop_reason
236237

237238
/**
@@ -599,6 +600,11 @@ class Connection {
599600
*/
600601
void reset_callbacks();
601602

603+
604+
using Recv_window_getter = delegate<uint32_t()>;
605+
void set_recv_wnd_getter(Recv_window_getter func)
606+
{ recv_wnd_getter = func; }
607+
602608
private:
603609
/** "Parent" for Connection. */
604610
TCP& host_;
@@ -626,6 +632,10 @@ class Connection {
626632
/** Round Trip Time Measurer */
627633
RTTM rttm;
628634

635+
/** Function from where to retrieve
636+
* the current recv window size for this connection */
637+
Recv_window_getter recv_wnd_getter;
638+
629639
/** Callbacks */
630640
ConnectCallback on_connect_;
631641
DisconnectCallback on_disconnect_;

api/net/tcp/tcp.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,15 @@ namespace net {
518518
return this->cpu_id;
519519
}
520520

521+
/**
522+
* @brief Return a value that's supposed to describe how much
523+
* a connection should announce as it's RCV WND,
524+
* with regards to the whole system.
525+
*
526+
* @return A RCV WND value, maximum 1GB
527+
*/
528+
static uint32_t global_recv_wnd();
529+
521530
private:
522531
IPStack& inet_;
523532
Listeners listeners_;

src/net/tcp/connection.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Connection::Connection(TCP& host, Socket local, Socket remote, ConnectCallback c
3636
cb{host_.window_size()},
3737
read_request(nullptr),
3838
writeq(),
39+
recv_wnd_getter{TCP::global_recv_wnd},
3940
on_connect_{std::move(callback)},
4041
on_disconnect_({this, &Connection::default_on_disconnect}),
4142
rtx_timer({this, &Connection::rtx_timeout}),
@@ -323,7 +324,9 @@ Packet_view_ptr Connection::create_outgoing_packet()
323324
// Set Destination (remote)
324325
packet->set_destination(remote_);
325326

326-
packet->set_win(std::min((cb.RCV.WND >> cb.RCV.wind_shift), (uint32_t)default_window_size));
327+
const auto recv_wnd = recv_wnd_getter();
328+
//printf("recv_wnd %u\n", recv_wnd);
329+
packet->set_win(cb.RCV.WND >> cb.RCV.wind_shift);
327330

328331
if(cb.SND.TS_OK)
329332
packet->add_tcp_option_aligned<Option::opt_ts_align>(host_.get_ts_value(), cb.get_ts_recent());
@@ -683,6 +686,15 @@ void Connection::recv_data(const Packet_view& in)
683686
{
684687
Expects(in.has_tcp_data());
685688

689+
// just drop the packet if we don't have a recv wnd.
690+
// this is really awful and probably unnecesseary,
691+
// since it could be that we already preallocated that memory in our vector.
692+
// i also think we shouldn't reach this point due to State::check_seq checking
693+
// if we're inside the window. if packet is out of order tho we can change the RCV wnd (i think).
694+
if(recv_wnd_getter() == 0)
695+
drop(in, Drop_reason::RCV_WND_ZERO);
696+
697+
686698
// Keep track if a packet is being sent during the async read callback
687699
const auto snd_nxt = cb.SND.NXT;
688700

@@ -719,6 +731,8 @@ void Connection::recv_data(const Packet_view& in)
719731
const auto recv = read_request->insert(in.seq(), in.tcp_data(), length, in.isset(PSH));
720732
// this ensures that the data we ACK is actually put in our buffer.
721733
Ensures(recv == length);
734+
// adjust the rcv wnd to (maybe) new value
735+
cb.RCV.WND = recv_wnd_getter();
722736
}
723737
}
724738
// Packet out of order

src/net/tcp/tcp.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <rtc> // nanos_now (get_ts_value)
3030
#include <net/tcp/packet4_view.hpp>
3131
#include <net/tcp/packet6_view.hpp>
32+
#include <kernel/os.hpp>
3233

3334
using namespace std;
3435
using namespace net;
@@ -254,6 +255,8 @@ void TCP::receive(Packet_view& packet)
254255

255256
// No open connection found, find listener for destination
256257
debug("<TCP::receive> No connection found - looking for listener..\n");
258+
// TODO: Avoid creating a new connection if we're running out of memory.
259+
// something like "mem avail" > (max_buffer_limit * 3) maybe
257260
auto listener_it = find_listener(dest);
258261

259262
// Listener found => Create Listener
@@ -370,6 +373,15 @@ void TCP::reset_pmtu(Socket dest, IP4::PMTU pmtu) {
370373
}
371374
}
372375

376+
uint32_t TCP::global_recv_wnd()
377+
{
378+
// 80% of free mem
379+
// normalize to 0 to avoid negative value (???)
380+
ssize_t avail = std::max<ssize_t>((static_cast<ssize_t>(OS::heap_avail()) * 80 / 100) / 2, 0);
381+
//printf("heap: %zi avail: %zu\n", (ssize_t)OS::heap_avail(), avail);
382+
return std::min<size_t>(avail, (1 << 30)); // max can only be 1GB
383+
}
384+
373385
void TCP::transmit(tcp::Packet_view_ptr packet)
374386
{
375387
// Generate checksum.

0 commit comments

Comments
 (0)