Move ReadSctpMessage to a class
In preparation for reassembling partial messages in userspace.
Change-Id: Ifa530698058ea775362eee4ec1bf9e6e0d3dd5de
Signed-off-by: Austin Schuh <austin.schuh@bluerivertech.com>
diff --git a/aos/network/sctp_client.cc b/aos/network/sctp_client.cc
index 9e77a84..113b525 100644
--- a/aos/network/sctp_client.cc
+++ b/aos/network/sctp_client.cc
@@ -19,42 +19,23 @@
SctpClient::SctpClient(std::string_view remote_host, int remote_port,
int streams, std::string_view local_host, int local_port)
: sockaddr_remote_(ResolveSocket(remote_host, remote_port)),
- sockaddr_local_(ResolveSocket(local_host, local_port)),
- fd_(socket(sockaddr_local_.ss_family, SOCK_SEQPACKET, IPPROTO_SCTP)) {
- LOG(INFO) << "socket(" << Family(sockaddr_local_)
- << ", SOCK_SEQPACKET, IPPROTOSCTP) = " << fd_;
- PCHECK(fd_ != -1);
-
- {
- // Per https://tools.ietf.org/html/rfc6458
- // Setting this to !0 allows event notifications to be interleaved
- // with data if enabled, and would have to be handled in the code.
- // Enabling interleaving would only matter during congestion, which
- // typically only happens during application startup.
- int interleaving = 0;
- PCHECK(setsockopt(fd_, IPPROTO_SCTP, SCTP_FRAGMENT_INTERLEAVE,
- &interleaving, sizeof(interleaving)) == 0);
- }
+ sockaddr_local_(ResolveSocket(local_host, local_port)) {
+ sctp_.OpenSocket(sockaddr_local_);
{
struct sctp_initmsg initmsg;
memset(&initmsg, 0, sizeof(struct sctp_initmsg));
initmsg.sinit_num_ostreams = streams;
initmsg.sinit_max_instreams = streams;
- PCHECK(setsockopt(fd_, IPPROTO_SCTP, SCTP_INITMSG, &initmsg,
+ PCHECK(setsockopt(fd(), IPPROTO_SCTP, SCTP_INITMSG, &initmsg,
sizeof(struct sctp_initmsg)) == 0);
}
{
- int on = 1;
- PCHECK(setsockopt(fd_, IPPROTO_SCTP, SCTP_RECVRCVINFO, &on, sizeof(int)) ==
- 0);
- }
- {
// Servers send promptly. Clients don't.
// TODO(austin): Revisit this assumption when we have time sync.
int on = 0;
- PCHECK(setsockopt(fd_, IPPROTO_SCTP, SCTP_NODELAY, &on, sizeof(int)) == 0);
+ PCHECK(setsockopt(fd(), IPPROTO_SCTP, SCTP_NODELAY, &on, sizeof(int)) == 0);
}
{
@@ -64,70 +45,15 @@
memset(&subscribe, 0, sizeof(subscribe));
subscribe.sctp_association_event = 1;
subscribe.sctp_stream_change_event = 1;
- PCHECK(setsockopt(fd_, SOL_SCTP, SCTP_EVENTS, (char *)&subscribe,
+ PCHECK(setsockopt(fd(), SOL_SCTP, SCTP_EVENTS, (char *)&subscribe,
sizeof(subscribe)) == 0);
}
- PCHECK(bind(fd_, (struct sockaddr *)&sockaddr_local_,
+ PCHECK(bind(fd(), (struct sockaddr *)&sockaddr_local_,
sockaddr_local_.ss_family == AF_INET6
? sizeof(struct sockaddr_in6)
: sizeof(struct sockaddr_in)) == 0);
- VLOG(1) << "bind(" << fd_ << ", " << Address(sockaddr_local_) << ")";
-}
-
-aos::unique_c_ptr<Message> SctpClient::Read() {
- return ReadSctpMessage(fd_, max_size_);
-}
-
-bool SctpClient::Send(int stream, std::string_view data, int time_to_live) {
- struct iovec iov;
- iov.iov_base = const_cast<char *>(data.data());
- iov.iov_len = data.size();
-
- struct msghdr outmsg;
- // Target to send to.
- outmsg.msg_name = &sockaddr_remote_;
- outmsg.msg_namelen = sizeof(struct sockaddr_storage);
- VLOG(1) << "Sending to " << Address(sockaddr_remote_);
-
- // Data to send.
- outmsg.msg_iov = &iov;
- outmsg.msg_iovlen = 1;
-
- // Build up the sndinfo message.
- char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
- outmsg.msg_control = outcmsg;
- outmsg.msg_controllen = sizeof(outcmsg);
- outmsg.msg_flags = 0;
-
- struct cmsghdr *cmsg = CMSG_FIRSTHDR(&outmsg);
- cmsg->cmsg_level = IPPROTO_SCTP;
- cmsg->cmsg_type = SCTP_SNDRCV;
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
-
- outmsg.msg_controllen = cmsg->cmsg_len;
- struct sctp_sndrcvinfo *sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
- memset(sinfo, 0, sizeof(struct sctp_sndrcvinfo));
- sinfo->sinfo_ppid = rand();
- sinfo->sinfo_stream = stream;
- sinfo->sinfo_context = 19;
- sinfo->sinfo_flags = 0;
- sinfo->sinfo_timetolive = time_to_live;
-
- // And send.
- const ssize_t size = sendmsg(fd_, &outmsg, MSG_NOSIGNAL | MSG_DONTWAIT);
- if (size == -1) {
- if (errno != EPIPE && errno != EAGAIN && errno != ESHUTDOWN) {
- PCHECK(size == static_cast<ssize_t>(data.size()));
- } else {
- return false;
- }
- } else {
- CHECK_EQ(static_cast<ssize_t>(data.size()), size);
- }
-
- VLOG(1) << "Sent " << data.size();
- return true;
+ VLOG(1) << "bind(" << fd() << ", " << Address(sockaddr_local_) << ")";
}
void SctpClient::LogSctpStatus(sctp_assoc_t assoc_id) {