blob: 427f828c12059cdac47b03bac02b14bf734830ca [file] [log] [blame]
Austin Schuhe84c3ed2019-12-14 15:29:48 -08001#ifndef AOS_NETWORK_SCTP_LIB_H_
2#define AOS_NETWORK_SCTP_LIB_H_
3
4#include <arpa/inet.h>
5#include <netinet/sctp.h>
6
7#include <memory>
Austin Schuh507f7582021-07-31 20:39:55 -07008#include <optional>
Austin Schuhe84c3ed2019-12-14 15:29:48 -08009#include <string>
10#include <string_view>
11
12#include "aos/unique_malloc_ptr.h"
13#include "gflags/gflags.h"
14#include "glog/logging.h"
15
16namespace aos {
17namespace message_bridge {
18
19// Resolves a socket and returns the address. This can be either an ipv4 or
20// ipv6 address.
21struct sockaddr_storage ResolveSocket(std::string_view host, int port);
22
23// Returns a formatted version of the address.
24std::string Address(const struct sockaddr_storage &sockaddr);
25// Returns a formatted version of the address family.
26std::string_view Family(const struct sockaddr_storage &sockaddr);
27
28// Message received.
29// This message is malloced bigger than needed and the extra space after it is
30// the data.
31struct Message {
32 // Struct to let us force data to be well aligned.
33 struct OveralignedChar {
34 uint8_t data alignas(32);
35 };
36
37 // Headers.
38 struct {
39 struct sctp_rcvinfo rcvinfo;
40 } header;
41
42 // Address of the sender.
43 struct sockaddr_storage sin;
44
45 // Data type. Is it a block of data, or is it a struct sctp_notification?
46 enum MessageType { kMessage, kNotification } message_type;
47
48 size_t size = 0u;
49 uint8_t *mutable_data() {
50 return reinterpret_cast<uint8_t *>(&actual_data[0].data);
51 }
52 const uint8_t *data() const {
53 return reinterpret_cast<const uint8_t *>(&actual_data[0].data);
54 }
55
Austin Schuhc4202572021-03-31 21:06:55 -070056 uint32_t partial_deliveries = 0;
57
Austin Schuhe84c3ed2019-12-14 15:29:48 -080058 // Returns a human readable peer IP address.
59 std::string PeerAddress() const;
60
61 // Prints out the RcvInfo structure.
62 void LogRcvInfo() const;
63
64 // The start of the data.
65 OveralignedChar actual_data[];
66};
67
68void PrintNotification(const Message *msg);
69
70std::string GetHostname();
71
72// Gets and logs the contents of the sctp_status message.
73void LogSctpStatus(int fd, sctp_assoc_t assoc_id);
74
Austin Schuh507f7582021-07-31 20:39:55 -070075// Manages reading and writing SCTP messages.
76class SctpReadWrite {
77 public:
78 SctpReadWrite() = default;
79 ~SctpReadWrite() { CloseSocket(); }
80
81 // Opens a new socket.
82 void OpenSocket(const struct sockaddr_storage &sockaddr_local);
83
84 // Sends a message to the kernel.
85 // Returns true for success. Will not send a partial message on failure.
86 bool SendMessage(int stream, std::string_view data, int time_to_live,
87 std::optional<struct sockaddr_storage> sockaddr_remote,
88 sctp_assoc_t snd_assoc_id);
89
90 // Reads from the kernel until a complete message is received or it blocks.
91 // Returns nullptr if the kernel blocks before returning a complete message.
92 aos::unique_c_ptr<Message> ReadMessage();
93
94 int fd() const { return fd_; }
95
96 void SetMaxSize(size_t max_size) {
97 max_size_ = max_size;
98 if (fd_ != -1) {
99 DoSetMaxSize();
100 }
101 }
102
103 private:
104 void CloseSocket();
105 void DoSetMaxSize();
106
107 int fd_ = -1;
108
109 // We use this as a unique identifier that just increments for each message.
110 uint32_t send_ppid_ = 0;
111
112 size_t max_size_ = 1000;
113};
Austin Schuhe84c3ed2019-12-14 15:29:48 -0800114
Austin Schuh2fe4b712020-03-15 14:21:45 -0700115// Returns the max network buffer available for reading for a socket.
116size_t ReadRMemMax();
117// Returns the max network buffer available for writing for a socket.
118size_t ReadWMemMax();
119
Austin Schuhe84c3ed2019-12-14 15:29:48 -0800120} // namespace message_bridge
121} // namespace aos
122
123#endif // AOS_NETWORK_SCTP_LIB_H_