2 #include <netinet/tcp.h>
3 #include <sys/socket.h>
6 #include "asn1_message.h"
7 #include "logging/logging.h"
8 #include "utilities/dequeue_buffer.h"
9 #include "utilities/utils.h"
12 #define MSG_NOSIGNAL 0
15 int Asn1StringAppendCallback(
const void* buffer,
size_t size,
void* priv) {
16 auto* out_str =
static_cast<std::string*
>(priv);
17 out_str->append(std::string(
static_cast<const char*
>(buffer), size));
25 int Asn1SocketWriteCallback(
const void* buffer,
size_t size,
void* priv) {
26 auto sock =
reinterpret_cast<int*
>(priv);
27 assert(sock !=
nullptr);
30 const auto* b =
static_cast<const char*
>(buffer);
36 ssize_t written = send(*sock, b + pos, len, MSG_NOSIGNAL);
38 LOG_ERROR <<
"write: " << std::strerror(errno);
41 len -=
static_cast<size_t>(written);
42 pos +=
static_cast<size_t>(written);
47 std::string ToString(
const OCTET_STRING_t& octet_str) {
48 return std::string(
reinterpret_cast<const char*
>(octet_str.buf),
static_cast<size_t>(octet_str.size));
51 void SetString(OCTET_STRING_t* dest,
const std::string& str) {
52 OCTET_STRING_fromBuf(dest, str.c_str(),
static_cast<int>(str.size()));
55 Asn1Message::Ptr Asn1Rpc(
const Asn1Message::Ptr& tx,
int con_fd) {
56 der_encode(&asn_DEF_AKIpUptaneMes, &tx->msg_, Asn1SocketWriteCallback, &con_fd);
60 setsockopt(con_fd, IPPROTO_TCP, TCP_NODELAY, &no_delay,
sizeof(
int));
62 setsockopt(con_fd, IPPROTO_TCP, TCP_NODELAY, &no_delay,
sizeof(
int));
64 AKIpUptaneMes_t* m =
nullptr;
66 asn_codec_ctx_s context{};
71 received = recv(con_fd, buffer.
Tail(), buffer.
TailSpace(), 0);
73 LOG_ERROR <<
"Failed to read data from a coonnection socket: " << strerror(errno);
76 LOG_TRACE <<
"Asn1Rpc read " << Utils::toBase64(std::string(buffer.
Tail(),
static_cast<size_t>(received)));
78 res = ber_decode(&context, &asn_DEF_AKIpUptaneMes,
reinterpret_cast<void**
>(&m), buffer.
Head(), buffer.
Size());
80 }
while (res.code == RC_WMORE && received > 0);
84 if (res.code != RC_OK) {
85 LOG_DEBUG <<
"Asn1Rpc decoding failed";
86 msg->present(AKIpUptaneMes_PR_NOTHING);
92 Asn1Message::Ptr Asn1Rpc(
const Asn1Message::Ptr& tx,
const std::pair<std::string, uint16_t>& addr) {
95 if (connection.connect() < 0) {
96 LOG_ERROR <<
"Failed to connect to the Secondary ( " << addr.first <<
":" << addr.second
97 <<
"): " << std::strerror(errno);
100 return Asn1Rpc(tx, *connection);