aos/network: client to abort connection with no data
One problem we have seen is that the server appears to
successfully receive and process a connect message,
but never sends data. Because the server never sends
data, the client keeps sending the connect message at
kReconnectTimeout (3) second intervals. But the SCTP
state never changes.
If we can reasonably expect that there should be data
within 3 seconds and that failing to receive data also
means the connection has failed in some way, force SCTP
to start over by sending an abort. This results in an
SCTP_ASSOC_CHANGE(COMMUNICATION_LOST) notification
regardless of the state of the other side of the
connection, which will call NodeDisconnected and mark
the connection as down.
This is not guaranteed to fix the issues we were seeing,
but hopefully avoids the SCTP connection getting stuck
in a buggy state.
It may incidentally also force a reconnect faster when
an ethernet cable is disconnected and reconnected.
Change-Id: I6fdd0eed9bbe6a694152363ade48706b057cba6d
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/network/sctp_client.h b/aos/network/sctp_client.h
index 9356612..1ba32ff 100644
--- a/aos/network/sctp_client.h
+++ b/aos/network/sctp_client.h
@@ -26,9 +26,13 @@
// Sends a block of data on a stream with a TTL.
// TODO(austin): time_to_live should be a chrono::duration
bool Send(int stream, std::string_view data, int time_to_live) {
- return sctp_.SendMessage(stream, data, time_to_live, sockaddr_remote_, 0);
+ return sctp_.SendMessage(stream, data, time_to_live, sockaddr_remote_,
+ sac_assoc_id_);
}
+ // Aborts a connection. Returns true on success.
+ bool Abort() { return sctp_.Abort(sac_assoc_id_); }
+
int fd() { return sctp_.fd(); }
// Enables the priority scheduler. This is a SCTP feature which lets us
@@ -45,10 +49,17 @@
void SetMaxSize(size_t max_size) { sctp_.SetMaxSize(max_size); }
+ void SetAssociationId(sctp_assoc_t sac_assoc_id) {
+ sac_assoc_id_ = sac_assoc_id;
+ }
+
private:
struct sockaddr_storage sockaddr_remote_;
struct sockaddr_storage sockaddr_local_;
SctpReadWrite sctp_;
+
+ // Valid if != 0.
+ sctp_assoc_t sac_assoc_id_ = 0;
};
} // namespace message_bridge