|
From: Erik R. <er...@om...> - 2016-05-11 21:35:56
|
> The only legal and reliable way I can think of to indicate a reset, if
> the message can't be completed, is to close the socket. So liblo
> checks for an error return from send() and closes the socket in that
> case.
Yeah, and that seems to work well.
> What you discovered is that an inundated receiving socket and produce
> send() errors. (I think.) However, in a sense this is probably the
> right thing to do, as it is similar to a DDoS attack, so dropping the
> connection is probably fine.
I agree that dropping the connection is fine! But a partial send must also be considered an error, therefore closing the socket – which it doesn’t, at present. A check in send_data() is needed:
do {
ret = send(sock, data, len, MSG_NOSIGNAL);
if (ret >= 0 && ret != len) {
// Close socket
}
if (a->protocol == LO_TCP)
ai = ai->ai_next;
else
ai = 0;
} while (ret == -1 && ai != NULL);
(Actually, the first send() where the message size is send should probably also be checked, even though the unlikelihood of a partial send of 4 bytes…)
> You should organize your system to not overload the server.
Definitely! Actually, I’ve already changed my application so that the reading thread just decodes the messages and pass them in a queue to another thread, which then dispatches them. This way, a lengthy operation doesn’t stall the read process, so this minimizes the risk of a full send buffer on the server side. So far, it seems to work well!
Erik
|