blob: 6b40600bc785c775dd6d429faf24d6b1f12f89df [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>
Austin Schuha705d782021-07-31 20:40:00 -070011#include <vector>
Austin Schuhe84c3ed2019-12-14 15:29:48 -080012
13#include "aos/unique_malloc_ptr.h"
14#include "gflags/gflags.h"
15#include "glog/logging.h"
16
17namespace aos {
18namespace message_bridge {
19
20// Resolves a socket and returns the address. This can be either an ipv4 or
21// ipv6 address.
22struct sockaddr_storage ResolveSocket(std::string_view host, int port);
23
24// Returns a formatted version of the address.
25std::string Address(const struct sockaddr_storage &sockaddr);
26// Returns a formatted version of the address family.
27std::string_view Family(const struct sockaddr_storage &sockaddr);
28
29// Message received.
30// This message is malloced bigger than needed and the extra space after it is
31// the data.
32struct Message {
33 // Struct to let us force data to be well aligned.
34 struct OveralignedChar {
35 uint8_t data alignas(32);
36 };
37
38 // Headers.
39 struct {
40 struct sctp_rcvinfo rcvinfo;
41 } header;
42
43 // Address of the sender.
44 struct sockaddr_storage sin;
45
46 // Data type. Is it a block of data, or is it a struct sctp_notification?
47 enum MessageType { kMessage, kNotification } message_type;
48
49 size_t size = 0u;
50 uint8_t *mutable_data() {
51 return reinterpret_cast<uint8_t *>(&actual_data[0].data);
52 }
53 const uint8_t *data() const {
54 return reinterpret_cast<const uint8_t *>(&actual_data[0].data);
55 }
56
Austin Schuhc4202572021-03-31 21:06:55 -070057 uint32_t partial_deliveries = 0;
58
Austin Schuhe84c3ed2019-12-14 15:29:48 -080059 // Returns a human readable peer IP address.
60 std::string PeerAddress() const;
61
62 // Prints out the RcvInfo structure.
63 void LogRcvInfo() const;
64
65 // The start of the data.
66 OveralignedChar actual_data[];
67};
68
69void PrintNotification(const Message *msg);
70
71std::string GetHostname();
72
73// Gets and logs the contents of the sctp_status message.
74void LogSctpStatus(int fd, sctp_assoc_t assoc_id);
75
Austin Schuh507f7582021-07-31 20:39:55 -070076// Manages reading and writing SCTP messages.
77class SctpReadWrite {
78 public:
79 SctpReadWrite() = default;
80 ~SctpReadWrite() { CloseSocket(); }
81
82 // Opens a new socket.
83 void OpenSocket(const struct sockaddr_storage &sockaddr_local);
84
85 // Sends a message to the kernel.
86 // Returns true for success. Will not send a partial message on failure.
87 bool SendMessage(int stream, std::string_view data, int time_to_live,
88 std::optional<struct sockaddr_storage> sockaddr_remote,
89 sctp_assoc_t snd_assoc_id);
90
91 // Reads from the kernel until a complete message is received or it blocks.
92 // Returns nullptr if the kernel blocks before returning a complete message.
93 aos::unique_c_ptr<Message> ReadMessage();
94
95 int fd() const { return fd_; }
96
97 void SetMaxSize(size_t max_size) {
Austin Schuha705d782021-07-31 20:40:00 -070098 CHECK(partial_messages_.empty())
99 << ": May not update size with queued fragments because we do not "
100 "track individual message sizes";
Austin Schuh507f7582021-07-31 20:39:55 -0700101 max_size_ = max_size;
102 if (fd_ != -1) {
103 DoSetMaxSize();
104 }
105 }
106
107 private:
108 void CloseSocket();
109 void DoSetMaxSize();
110
Austin Schuha705d782021-07-31 20:40:00 -0700111 // Examines a notification message for ones we handle here.
112 // Returns true if the notification was handled by this class.
113 bool ProcessNotification(const Message *message);
114
Austin Schuh507f7582021-07-31 20:39:55 -0700115 int fd_ = -1;
116
117 // We use this as a unique identifier that just increments for each message.
118 uint32_t send_ppid_ = 0;
119
120 size_t max_size_ = 1000;
Austin Schuha705d782021-07-31 20:40:00 -0700121
122 std::vector<aos::unique_c_ptr<Message>> partial_messages_;
Austin Schuh507f7582021-07-31 20:39:55 -0700123};
Austin Schuhe84c3ed2019-12-14 15:29:48 -0800124
Austin Schuh2fe4b712020-03-15 14:21:45 -0700125// Returns the max network buffer available for reading for a socket.
126size_t ReadRMemMax();
127// Returns the max network buffer available for writing for a socket.
128size_t ReadWMemMax();
129
Austin Schuhe84c3ed2019-12-14 15:29:48 -0800130} // namespace message_bridge
131} // namespace aos
132
133#endif // AOS_NETWORK_SCTP_LIB_H_