Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net: tcp: Allow application to manage TCP receive window #1002

Merged
merged 2 commits into from
Aug 5, 2017

Conversation

pfalcon
Copy link
Contributor

@pfalcon pfalcon commented Aug 3, 2017

This is rework of #81. As we didn't agree how TCP recv window management should work on the level of native Zephyr networking API, the new patch makes the management completely optional. By default, all apps continue to work as they did before (where there's static window size). However, apps which queue up data, can both shrink and widen it as needed. This feature is required and used by BSD Sockets implementation to achieve reliable transfers of large amounts of data (megabytes).

Copy link
Member

@jukkar jukkar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Paul for continuing this effort, there are these tricky problems with TCP that needs to be addressed. The send window handling is probably more difficult one to solve.

You probably noticed this already but Signed-off-by: is missing from second patch.


ret = packet_received(conn, pkt, context->tcp->recv_user_data);

context->tcp->send_ack += data_len;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Earlier the value of send_ack was updated before a call to packet_received(), shouldn't we do it like that here too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is generally more correct. ACK sequence should be updated after we (== app) have received the data, and we (== app) received it after return from the receive callback, not before it.

I'll address the other comments.

@@ -1187,10 +1187,18 @@ NET_CONN_CB(tcp_established)
}

set_appdata_values(pkt, IPPROTO_TCP);
context->tcp->send_ack += net_pkt_appdatalen(pkt);

uint16_t data_len = net_pkt_appdatalen(pkt);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are introducing data_len here in the middle of function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

return -EPROTOTYPE;
}

context->tcp->recv_wnd += delta;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we check here that the delta is not too large or small?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, we can, but it will make code much less pretty ;-). Do we really need to do that now? ;-)

Copy link
Member

@jukkar jukkar Aug 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, we can, but it will make code much less pretty ;-). Do we really need to do that now? ;-)

I think we need to, otherwise this will be forgotten :)

The recv_wnd is uint16_t (actually it should be u16_t, missed this on my first review), and we just cannot blindly +- some user specified int value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

recv_wnd is uint16_t (actually it should be u16_t

Sorry, this is all is based on the older patch made before u*_t refactor. Now fixed.

Ok, to do bounds checking right, we should consider: is u16_t the right type for recv_wnd value (as stored in struct net_tcp)?

Copy link
Member

@jukkar jukkar Aug 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably u16_t is enough here, I mean would it make sense to have a window size that is larger than 65kb in Zephyr?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think 64K should be quite enough for Zephyr. Ok, I'll use s32_t arithmetics to check bounds of u16_t value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@pfalcon pfalcon force-pushed the net-tcp-recv-wnd branch 2 times, most recently from 948553a to 96045ed Compare August 4, 2017 15:31
pfalcon added 2 commits August 4, 2017 22:37
This fixes the existing situation that "if application buffers data,
it's the problem of application". It's actually the problem of the
stack, as it doesn't allow application to control receive window,
and without this control, any buffer will overflow, peer packets
will be dropped, peer won't receive acks for them, and will employ
exponential backoff, the connection will crawl to a halt.

This patch adds net_context_tcp_recved() function which an
application must explicitly call when it *processes* data, to
advance receive window.

Jira: ZEP-1999

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
As we buffer incoming packets in receive callbacks, we must decrease
receive window to avoid situation that incoming stream for one socket
uses up all buffers in the system and causes deadlock. Once user app
consumes queued data using recv() call, we increase window again.

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
@jukkar jukkar merged commit b7e3739 into zephyrproject-rtos:master Aug 5, 2017
@jukkar jukkar added the net label Aug 5, 2017
nagineni pushed a commit to nagineni/zephyr that referenced this pull request Nov 20, 2017
Signed-off-by: Brian J Jones <brian.j.jones@intel.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants