-
Notifications
You must be signed in to change notification settings - Fork 174
read.c (tds_get_n): Avoid potential hangs on short replies. #585
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
Conversation
Don't bother trying to receive data following a packet marked as last; rather, bail if still short. Whenever bailing, close the socket on the way out to contain the damage from having fallen out of sync. Signed-off-by: Aaron M. Ucko <[email protected]>
| } | ||
| need -= have; | ||
| if (TDS_UNLIKELY(tds_read_packet(tds) < 0)) | ||
| if (TDS_UNLIKELY(tds->recv_packet->capacity < 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
capacity can't be so small
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair point; I just wanted to preclude any possibility that the following array access would be invalid.
| need -= have; | ||
| if (TDS_UNLIKELY(tds_read_packet(tds) < 0)) | ||
| if (TDS_UNLIKELY(tds->recv_packet->capacity < 2 | ||
| || tds->in_buf[1] != 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you want to test only the final bit and not all the flags. It makes sense, if no more packets are expected data should not continue on next packet. Wondering if tds_get_n would be called for first bytes of the packet series. Not sure if this can even happen however. I don't think cancellation apply here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, yeah, testing just the low-order bit is more appropriate, though I'm not sure how much difference it makes in practice.
The situation originally motivating this change was canceling blob retrieval, which at least in the case of the OpenServer instance I was using, could yield a truncated row response giving a blob's full length but containing only part of its body, leading to loss of synchronization that would otherwise typically culminate in hangs. Perhaps the server should have acknowledged cancellation more clearly, but it did at least set that flag correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting! So you are telling the way Open Server handles cancellation is different? Maybe we can support it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, at least historically. Maybe it's been fixed since, but a little extra caution here can't hurt.
|
Merged, with minor changes. Sorry for the delay. One thing that puzzled me is why it did not fail when we get to a new packet; probably the packet always start with a byte read by |
Don't bother trying to receive data following a packet marked as last; rather, bail if still short. Whenever bailing, close the socket on the way out to contain the damage from having fallen out of sync.
Split from #555.