1 #include "secondary_tcp_server.h"
3 #include "AKIpUptaneMes.h"
4 #include "asn1/asn1_message.h"
5 #include "logging/logging.h"
6 #include "uptane/secondaryinterface.h"
7 #include "utilities/dequeue_buffer.h"
9 #include <netinet/tcp.h>
12 in_port_t primary_port, in_port_t port)
14 ConnectionSocket conn_socket(primary_ip, primary_port, listen_socket_.port());
15 if (conn_socket.connect() == 0) {
16 LOG_INFO <<
"Connected to Primary, sending info about this secondary...";
17 HandleOneConnection(*conn_socket);
19 LOG_INFO <<
"Failed to connect to Primary";
24 if (listen(*listen_socket_, SOMAXCONN) < 0) {
25 throw std::system_error(errno, std::system_category(),
"listen");
27 LOG_INFO <<
"Secondary TCP server listens on " << listen_socket_.toString();
29 while (keep_running_.load()) {
31 sockaddr_storage peer_sa{};
32 socklen_t peer_sa_size =
sizeof(sockaddr_storage);
34 LOG_DEBUG <<
"Waiting for connection from client...";
35 if ((con_fd = accept(*listen_socket_, reinterpret_cast<sockaddr *>(&peer_sa), &peer_sa_size)) == -1) {
36 LOG_INFO <<
"Socket accept failed. aborting";
39 LOG_DEBUG <<
"Connected...";
40 HandleOneConnection(con_fd);
41 LOG_DEBUG <<
"Client disconnected";
43 LOG_INFO <<
"Secondary TCP server exit";
46 void SecondaryTcpServer::stop() {
47 keep_running_ =
false;
52 in_port_t SecondaryTcpServer::port()
const {
return listen_socket_.port(); }
54 void SecondaryTcpServer::HandleOneConnection(
int socket) {
63 AKIpUptaneMes_t *m =
nullptr;
65 asn_codec_ctx_s context{};
68 received = recv(socket, buffer.
Tail(), buffer.
TailSpace(), 0);
69 LOG_TRACE <<
"Got " << received <<
" bytes "
70 << Utils::toBase64(std::string(buffer.
Tail(), static_cast<size_t>(received)));
72 res = ber_decode(&context, &asn_DEF_AKIpUptaneMes, reinterpret_cast<void **>(&m), buffer.
Head(), buffer.
Size());
74 }
while (res.code == RC_WMORE && received > 0);
78 if (res.code != RC_OK) {
84 switch (msg->present()) {
85 case AKIpUptaneMes_PR_getInfoReq: {
89 resp->present(AKIpUptaneMes_PR_getInfoResp);
90 auto r = resp->getInfoResp();
91 SetString(&r->ecuSerial, serial.ToString());
92 SetString(&r->hwId, hw_id.ToString());
93 r->keyType = static_cast<AKIpUptaneKeyType_t>(pk.Type());
94 SetString(&r->key, pk.Value());
96 case AKIpUptaneMes_PR_manifestReq: {
97 std::string manifest = Utils::jsonToStr(impl_.getManifest());
98 resp->present(AKIpUptaneMes_PR_manifestResp);
99 auto r = resp->manifestResp();
100 r->manifest.present = manifest_PR_json;
101 SetString(&r->manifest.choice.json, manifest);
103 case AKIpUptaneMes_PR_putMetaReq: {
104 auto md = msg->putMetaReq();
106 if (md->image.present == image_PR_json) {
107 meta_pack.image_root = ToString(md->image.choice.json.root);
108 meta_pack.image_targets = ToString(md->image.choice.json.targets);
109 meta_pack.image_snapshot = ToString(md->image.choice.json.snapshot);
110 meta_pack.image_timestamp = ToString(md->image.choice.json.timestamp);
112 LOG_WARNING <<
"Images metadata in unknown format:" << md->image.present;
115 if (md->director.present == director_PR_json) {
116 meta_pack.director_root = ToString(md->director.choice.json.root);
117 meta_pack.director_targets = ToString(md->director.choice.json.targets);
119 LOG_WARNING <<
"Director metadata in unknown format:" << md->director.present;
123 ok = impl_.putMetadata(meta_pack);
125 LOG_WARNING <<
"Rejected metadata push because of security failure" << e.what();
128 resp->present(AKIpUptaneMes_PR_putMetaResp);
129 auto r = resp->putMetaResp();
130 r->result = ok ? AKInstallationResult_success : AKInstallationResult_failure;
132 case AKIpUptaneMes_PR_sendFirmwareReq: {
133 auto fw = msg->sendFirmwareReq();
134 auto send_firmware_result = impl_.sendFirmware(ToString(fw->firmware));
135 resp->present(AKIpUptaneMes_PR_sendFirmwareResp);
136 auto r = resp->sendFirmwareResp();
137 r->result = send_firmware_result ? AKInstallationResult_success : AKInstallationResult_failure;
139 case AKIpUptaneMes_PR_installReq: {
140 auto request = msg->installReq();
142 auto install_result = impl_.install(ToString(request->hash));
144 resp->present(AKIpUptaneMes_PR_installResp);
145 auto response_message = resp->installResp();
146 response_message->result = static_cast<AKInstallationResultCode_t>(install_result);
149 LOG_ERROR <<
"Unrecognised message type:" << msg->present();
154 if (resp->present() != AKIpUptaneMes_PR_NOTHING) {
156 setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, &optval,
sizeof(
int));
157 asn_enc_rval_t encode_result =
158 der_encode(&asn_DEF_AKIpUptaneMes, &resp->msg_, Asn1SocketWriteCallback, reinterpret_cast<void *>(&socket));
159 if (encode_result.encoded == -1) {
163 setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, &optval,
sizeof(
int));
165 LOG_DEBUG <<
"Not sending a response to message " << msg->present();