blob: b387e07a31d9bc8654939cdf263ac4a2adb8c767 [file] [log] [blame]
Austin Schuhe84c3ed2019-12-14 15:29:48 -08001#include "aos/network/sctp_client.h"
2
3#include <arpa/inet.h>
Adam Snaiderbe263512023-05-18 20:40:23 -07004#include <linux/sctp.h>
Austin Schuhe84c3ed2019-12-14 15:29:48 -08005#include <net/if.h>
Austin Schuhe84c3ed2019-12-14 15:29:48 -08006#include <sys/socket.h>
Tyler Chatowbf0609c2021-07-31 16:13:27 -07007
8#include <cstdlib>
9#include <cstring>
Austin Schuhe84c3ed2019-12-14 15:29:48 -080010#include <string_view>
11
Austin Schuh99f7c6a2024-06-25 22:07:44 -070012#include "absl/flags/flag.h"
13#include "absl/log/check.h"
14#include "absl/log/log.h"
Philipp Schrader790cb542023-07-05 21:06:52 -070015
Austin Schuhe84c3ed2019-12-14 15:29:48 -080016#include "aos/network/sctp_lib.h"
17#include "aos/unique_malloc_ptr.h"
Austin Schuhe84c3ed2019-12-14 15:29:48 -080018
Austin Schuh99f7c6a2024-06-25 22:07:44 -070019ABSL_FLAG(int32_t, sinit_max_init_timeout, 0,
20 "Timeout in milliseconds for retrying the INIT packet when "
21 "connecting to the message bridge server");
Austin Schuh3c4af572021-11-11 18:47:33 -080022
Stephan Pleinesf63bde82024-01-13 15:59:33 -080023namespace aos::message_bridge {
Austin Schuhe84c3ed2019-12-14 15:29:48 -080024
25SctpClient::SctpClient(std::string_view remote_host, int remote_port,
Adam Snaider96a0f4b2023-05-18 20:41:19 -070026 int streams, std::string_view local_host, int local_port,
Adam Snaider9bb33442023-06-26 16:31:37 -070027 SctpAuthMethod requested_authentication)
28 : sctp_(requested_authentication) {
Austin Schuh0a0a8272021-12-08 13:19:32 -080029 bool use_ipv6 = Ipv6Enabled();
30 sockaddr_local_ = ResolveSocket(local_host, local_port, use_ipv6);
31 sockaddr_remote_ = ResolveSocket(remote_host, remote_port, use_ipv6);
Austin Schuh507f7582021-07-31 20:39:55 -070032 sctp_.OpenSocket(sockaddr_local_);
Austin Schuhe84c3ed2019-12-14 15:29:48 -080033
34 {
35 struct sctp_initmsg initmsg;
36 memset(&initmsg, 0, sizeof(struct sctp_initmsg));
37 initmsg.sinit_num_ostreams = streams;
38 initmsg.sinit_max_instreams = streams;
Austin Schuh3c4af572021-11-11 18:47:33 -080039 // Max timeout in milliseconds for the INIT packet.
Austin Schuh99f7c6a2024-06-25 22:07:44 -070040 initmsg.sinit_max_init_timeo = absl::GetFlag(FLAGS_sinit_max_init_timeout);
Austin Schuh507f7582021-07-31 20:39:55 -070041 PCHECK(setsockopt(fd(), IPPROTO_SCTP, SCTP_INITMSG, &initmsg,
Austin Schuhe84c3ed2019-12-14 15:29:48 -080042 sizeof(struct sctp_initmsg)) == 0);
43 }
44
45 {
Austin Schuh8e7034c2021-11-02 20:47:47 -070046 // Turn off the NAGLE algorithm so the timestamps heading back across the
47 // network arrive promptly.
48 int on = 1;
Austin Schuh507f7582021-07-31 20:39:55 -070049 PCHECK(setsockopt(fd(), IPPROTO_SCTP, SCTP_NODELAY, &on, sizeof(int)) == 0);
Austin Schuhe84c3ed2019-12-14 15:29:48 -080050 }
Austin Schuhe84c3ed2019-12-14 15:29:48 -080051}
52
53void SctpClient::LogSctpStatus(sctp_assoc_t assoc_id) {
54 message_bridge::LogSctpStatus(fd(), assoc_id);
55}
56
Sarah Newman1e1b0492023-01-12 14:57:31 -080057void SctpClient::SetPriorityScheduler([[maybe_unused]] sctp_assoc_t assoc_id) {
58// Kernel 4.9 does not have SCTP_SS_PRIO
59#ifdef SCTP_SS_PRIO
Jim Ostrowski5d5a44f2020-06-24 19:10:15 -070060 struct sctp_assoc_value scheduler;
61 memset(&scheduler, 0, sizeof(scheduler));
62 scheduler.assoc_id = assoc_id;
63 scheduler.assoc_value = SCTP_SS_PRIO;
64 if (setsockopt(fd(), IPPROTO_SCTP, SCTP_STREAM_SCHEDULER, &scheduler,
65 sizeof(scheduler)) != 0) {
James Kuszmaul18e71182023-09-04 15:32:49 -070066 PLOG(FATAL) << "Failed to set scheduler.";
Jim Ostrowski5d5a44f2020-06-24 19:10:15 -070067 }
Sarah Newman1e1b0492023-01-12 14:57:31 -080068#endif
Austin Schuhe84c3ed2019-12-14 15:29:48 -080069}
70
Stephan Pleinesf63bde82024-01-13 15:59:33 -080071} // namespace aos::message_bridge