blob: ab70c20233650fe9632849fda8e821ed1384a02e [file] [log] [blame]
Austin Schuhe84c3ed2019-12-14 15:29:48 -08001#include "aos/network/sctp_client.h"
2
3#include <arpa/inet.h>
4#include <net/if.h>
5#include <netinet/sctp.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
12#include "aos/network/sctp_lib.h"
13#include "aos/unique_malloc_ptr.h"
14#include "glog/logging.h"
15
Austin Schuh3c4af572021-11-11 18:47:33 -080016DEFINE_int32(sinit_max_init_timeout, 0,
17 "Timeout in milliseconds for retrying the INIT packet when "
18 "connecting to the message bridge server");
19
Austin Schuhe84c3ed2019-12-14 15:29:48 -080020namespace aos {
21namespace message_bridge {
22
23SctpClient::SctpClient(std::string_view remote_host, int remote_port,
Austin Schuh0a0a8272021-12-08 13:19:32 -080024 int streams, std::string_view local_host,
25 int local_port) {
26 bool use_ipv6 = Ipv6Enabled();
27 sockaddr_local_ = ResolveSocket(local_host, local_port, use_ipv6);
28 sockaddr_remote_ = ResolveSocket(remote_host, remote_port, use_ipv6);
Austin Schuh507f7582021-07-31 20:39:55 -070029 sctp_.OpenSocket(sockaddr_local_);
Austin Schuhe84c3ed2019-12-14 15:29:48 -080030
31 {
32 struct sctp_initmsg initmsg;
33 memset(&initmsg, 0, sizeof(struct sctp_initmsg));
34 initmsg.sinit_num_ostreams = streams;
35 initmsg.sinit_max_instreams = streams;
Austin Schuh3c4af572021-11-11 18:47:33 -080036 // Max timeout in milliseconds for the INIT packet.
37 initmsg.sinit_max_init_timeo = FLAGS_sinit_max_init_timeout;
Austin Schuh507f7582021-07-31 20:39:55 -070038 PCHECK(setsockopt(fd(), IPPROTO_SCTP, SCTP_INITMSG, &initmsg,
Austin Schuhe84c3ed2019-12-14 15:29:48 -080039 sizeof(struct sctp_initmsg)) == 0);
40 }
41
42 {
Austin Schuh8e7034c2021-11-02 20:47:47 -070043 // Turn off the NAGLE algorithm so the timestamps heading back across the
44 // network arrive promptly.
45 int on = 1;
Austin Schuh507f7582021-07-31 20:39:55 -070046 PCHECK(setsockopt(fd(), IPPROTO_SCTP, SCTP_NODELAY, &on, sizeof(int)) == 0);
Austin Schuhe84c3ed2019-12-14 15:29:48 -080047 }
Austin Schuhe84c3ed2019-12-14 15:29:48 -080048}
49
50void SctpClient::LogSctpStatus(sctp_assoc_t assoc_id) {
51 message_bridge::LogSctpStatus(fd(), assoc_id);
52}
53
Sarah Newman1e1b0492023-01-12 14:57:31 -080054void SctpClient::SetPriorityScheduler([[maybe_unused]] sctp_assoc_t assoc_id) {
55// Kernel 4.9 does not have SCTP_SS_PRIO
56#ifdef SCTP_SS_PRIO
Jim Ostrowski5d5a44f2020-06-24 19:10:15 -070057 struct sctp_assoc_value scheduler;
58 memset(&scheduler, 0, sizeof(scheduler));
59 scheduler.assoc_id = assoc_id;
60 scheduler.assoc_value = SCTP_SS_PRIO;
61 if (setsockopt(fd(), IPPROTO_SCTP, SCTP_STREAM_SCHEDULER, &scheduler,
62 sizeof(scheduler)) != 0) {
Sarah Newman29da5ed2022-04-28 18:51:18 -070063 LOG_FIRST_N(WARNING, 1) << "Failed to set scheduler: " << strerror(errno)
64 << " [" << errno << "]";
Jim Ostrowski5d5a44f2020-06-24 19:10:15 -070065 }
Sarah Newman1e1b0492023-01-12 14:57:31 -080066#endif
Austin Schuhe84c3ed2019-12-14 15:29:48 -080067}
68
69} // namespace message_bridge
70} // namespace aos