Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
ipc_helpers.cpp
Go to the documentation of this file.
3
4namespace sysio { namespace chain { namespace eosvmoc {
5
6static constexpr size_t max_message_size = 8192;
7static constexpr size_t max_num_fds = 4;
8
9std::tuple<bool, eosvmoc_message, std::vector<wrapped_fd>> read_message_with_fds(boost::asio::local::datagram_protocol::socket& s) {
10 return read_message_with_fds(s.native_handle());
11}
12
13std::tuple<bool, eosvmoc_message, std::vector<wrapped_fd>> read_message_with_fds(int fd) {
14 char buff[max_message_size];
15
16 struct msghdr msg = {};
17 struct cmsghdr* cmsg;
18
19 eosvmoc_message message;
20 std::vector<wrapped_fd> fds;
21
22 struct iovec io = {
23 .iov_base = buff,
24 .iov_len = sizeof(buff)
25 };
26 union {
27 char buf[CMSG_SPACE(max_num_fds * sizeof(int))];
28 struct cmsghdr align;
29 } u;
30
31 msg.msg_iov = &io;
32 msg.msg_iovlen = 1;
33 msg.msg_control = u.buf;
34 msg.msg_controllen = sizeof(u.buf);
35
36 int red;
37 do {
38 red = recvmsg(fd, &msg, 0);
39 } while(red == -1 && errno == EINTR);
40 if(red < 1 || static_cast<unsigned>(red) >= sizeof(buff))
41 return {false, message, std::move(fds)};
42
43 try {
44 fc::datastream<char*> ds(buff, red);
45 fc::raw::unpack(ds, message);
46 }
47 catch(...) {
48 return {false, message, std::move(fds)};
49 }
50
51 if(msg.msg_controllen) {
52 cmsg = CMSG_FIRSTHDR(&msg);
53 unsigned num_of_fds = (cmsg->cmsg_len - CMSG_LEN(0))/sizeof(int);
54 if(num_of_fds > max_num_fds)
55 return {false, message, std::move(fds)};
56 int* fd_ptr = (int*)CMSG_DATA(cmsg);
57 for(unsigned i = 0; i < num_of_fds; ++i)
58 fds.push_back(*fd_ptr++);
59 }
60
61 return {true, message, std::move(fds)};
62}
63
64bool write_message_with_fds(boost::asio::local::datagram_protocol::socket& s, const eosvmoc_message& message, const std::vector<wrapped_fd>& fds) {
65 return write_message_with_fds(s.native_handle(), message, fds);
66}
67
68bool write_message_with_fds(int fd_to_send_to, const eosvmoc_message& message, const std::vector<wrapped_fd>& fds) {
69 struct msghdr msg = {};
70 struct cmsghdr* cmsg;
71
72 size_t sz = fc::raw::pack_size(message);
73 if(sz > max_message_size)
74 return false;
75 char buff[max_message_size];
76 try {
77 fc::datastream<char*> ds(buff, max_message_size);
78 fc::raw::pack(ds, message);
79 }
80 catch(...) {
81 return false;
82 }
83
84 if(fds.size() > max_num_fds)
85 return false;
86
87 struct iovec io = {
88 .iov_base = buff,
89 .iov_len = sz
90 };
91 union {
92 char buf[CMSG_SPACE(max_num_fds * sizeof(int))];
93 struct cmsghdr align;
94 } u;
95
96 msg.msg_iov = &io;
97 msg.msg_iovlen = 1;
98 if(fds.size()) {
99 msg.msg_control = u.buf;
100 msg.msg_controllen = sizeof(u.buf);
101 cmsg = CMSG_FIRSTHDR(&msg);
102 cmsg->cmsg_level = SOL_SOCKET;
103 cmsg->cmsg_type = SCM_RIGHTS;
104 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * fds.size());
105 unsigned char* p = CMSG_DATA(cmsg);
106 for(const wrapped_fd& fd : fds) {
107 int thisfd = fd;
108 memcpy(p, &thisfd, sizeof(thisfd));
109 p += sizeof(thisfd);
110 }
111 }
112
113 int wrote;
114 do {
115 wrote = sendmsg(fd_to_send_to, &msg, 0);
116 } while(wrote == -1 && errno == EINTR);
117
118 return wrote >= 0;
119}
120
121std::vector<uint8_t> vector_for_memfd(const wrapped_fd& memfd) {
122 struct stat st;
123 FC_ASSERT(fstat(memfd, &st) == 0, "failed to get memfd size");
124
125 if(st.st_size == 0)
126 return std::vector<uint8_t>();
127
128 uint8_t* p = (uint8_t*)mmap(nullptr, st.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, memfd, 0);
129 FC_ASSERT(p != MAP_FAILED, "failed to map memfd");
130 std::vector<uint8_t> ret(p, p+st.st_size);
131 munmap(p, st.st_size);
132 return ret;
133}
134
135}}}
const mie::Vuint & p
Definition bn.cpp:27
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
void unpack(Stream &s, std::deque< T > &value)
Definition raw.hpp:540
void pack(Stream &s, const std::deque< T > &value)
Definition raw.hpp:531
size_t pack_size(const T &v)
Definition raw.hpp:671
std::vector< uint8_t > vector_for_memfd(const wrapped_fd &memfd)
bool write_message_with_fds(boost::asio::local::datagram_protocol::socket &s, const eosvmoc_message &message, const std::vector< wrapped_fd > &fds=std::vector< wrapped_fd >())
std::tuple< bool, eosvmoc_message, std::vector< wrapped_fd > > read_message_with_fds(boost::asio::local::datagram_protocol::socket &s)
std::variant< initialize_message, initalize_response_message, compile_wasm_message, evict_wasms_message, code_compilation_result_message, wasm_compilation_result_message > eosvmoc_message
unsigned char uint8_t
Definition stdint.h:124
CK_RV ret
char * s
uint8_t buf[2048]
memcpy((char *) pInfo->slotDescription, s, l)