blob: 113b525f4f3db164ec985573312f536567889282 [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
16namespace aos {
17namespace message_bridge {
18
19SctpClient::SctpClient(std::string_view remote_host, int remote_port,
20 int streams, std::string_view local_host, int local_port)
21 : sockaddr_remote_(ResolveSocket(remote_host, remote_port)),
Austin Schuh507f7582021-07-31 20:39:55 -070022 sockaddr_local_(ResolveSocket(local_host, local_port)) {
23 sctp_.OpenSocket(sockaddr_local_);
Austin Schuhe84c3ed2019-12-14 15:29:48 -080024
25 {
26 struct sctp_initmsg initmsg;
27 memset(&initmsg, 0, sizeof(struct sctp_initmsg));
28 initmsg.sinit_num_ostreams = streams;
29 initmsg.sinit_max_instreams = streams;
Austin Schuh507f7582021-07-31 20:39:55 -070030 PCHECK(setsockopt(fd(), IPPROTO_SCTP, SCTP_INITMSG, &initmsg,
Austin Schuhe84c3ed2019-12-14 15:29:48 -080031 sizeof(struct sctp_initmsg)) == 0);
32 }
33
34 {
Austin Schuhe84c3ed2019-12-14 15:29:48 -080035 // Servers send promptly. Clients don't.
36 // TODO(austin): Revisit this assumption when we have time sync.
37 int on = 0;
Austin Schuh507f7582021-07-31 20:39:55 -070038 PCHECK(setsockopt(fd(), IPPROTO_SCTP, SCTP_NODELAY, &on, sizeof(int)) == 0);
Austin Schuhe84c3ed2019-12-14 15:29:48 -080039 }
40
41 {
42 // TODO(austin): This is the old style registration... But, the sctp
43 // stack out in the wild for linux is old and primitive.
44 struct sctp_event_subscribe subscribe;
45 memset(&subscribe, 0, sizeof(subscribe));
Austin Schuhe84c3ed2019-12-14 15:29:48 -080046 subscribe.sctp_association_event = 1;
Austin Schuhf7777002020-09-01 18:41:28 -070047 subscribe.sctp_stream_change_event = 1;
Austin Schuh507f7582021-07-31 20:39:55 -070048 PCHECK(setsockopt(fd(), SOL_SCTP, SCTP_EVENTS, (char *)&subscribe,
Austin Schuhe84c3ed2019-12-14 15:29:48 -080049 sizeof(subscribe)) == 0);
50 }
51
Austin Schuh507f7582021-07-31 20:39:55 -070052 PCHECK(bind(fd(), (struct sockaddr *)&sockaddr_local_,
Austin Schuhe84c3ed2019-12-14 15:29:48 -080053 sockaddr_local_.ss_family == AF_INET6
54 ? sizeof(struct sockaddr_in6)
55 : sizeof(struct sockaddr_in)) == 0);
Austin Schuh507f7582021-07-31 20:39:55 -070056 VLOG(1) << "bind(" << fd() << ", " << Address(sockaddr_local_) << ")";
Austin Schuhe84c3ed2019-12-14 15:29:48 -080057}
58
59void SctpClient::LogSctpStatus(sctp_assoc_t assoc_id) {
60 message_bridge::LogSctpStatus(fd(), assoc_id);
61}
62
63void SctpClient::SetPriorityScheduler(sctp_assoc_t assoc_id) {
Jim Ostrowski5d5a44f2020-06-24 19:10:15 -070064 struct sctp_assoc_value scheduler;
65 memset(&scheduler, 0, sizeof(scheduler));
66 scheduler.assoc_id = assoc_id;
67 scheduler.assoc_value = SCTP_SS_PRIO;
68 if (setsockopt(fd(), IPPROTO_SCTP, SCTP_STREAM_SCHEDULER, &scheduler,
69 sizeof(scheduler)) != 0) {
70 PLOG(WARNING) << "Failed to set scheduler";
71 }
Austin Schuhe84c3ed2019-12-14 15:29:48 -080072}
73
74} // namespace message_bridge
75} // namespace aos