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,
bool reboot_after_install)
13 : impl_(secondary), listen_socket_(port), keep_running_(true), reboot_after_install_(reboot_after_install) {
14 if (primary_ip.empty()) {
18 ConnectionSocket conn_socket(primary_ip, primary_port, listen_socket_.port());
19 if (conn_socket.connect() == 0) {
20 LOG_INFO <<
"Connected to Primary, sending info about this Secondary.";
21 HandleOneConnection(*conn_socket);
23 LOG_INFO <<
"Failed to connect to Primary.";
28 if (listen(*listen_socket_, SOMAXCONN) < 0) {
29 throw std::system_error(errno, std::system_category(),
"listen");
31 LOG_INFO <<
"Secondary TCP server listening on " << listen_socket_.toString();
33 while (keep_running_.load()) {
34 sockaddr_storage peer_sa{};
35 socklen_t peer_sa_size =
sizeof(sockaddr_storage);
37 LOG_DEBUG <<
"Waiting for connection from Primary...";
38 int con_fd = accept(*listen_socket_, reinterpret_cast<sockaddr *>(&peer_sa), &peer_sa_size);
40 LOG_INFO <<
"Socket accept failed, aborting.";
44 LOG_DEBUG <<
"Connected to Primary.";
45 bool continue_serving = HandleOneConnection(*con_socket);
46 LOG_DEBUG <<
"Primary disconnected.";
47 if (!continue_serving) {
51 LOG_INFO <<
"Secondary TCP server exiting.";
54 void SecondaryTcpServer::stop() {
55 keep_running_ =
false;
60 in_port_t SecondaryTcpServer::port()
const {
return listen_socket_.port(); }
61 SecondaryTcpServer::ExitReason SecondaryTcpServer::exit_reason()
const {
return exit_reason_; }
63 bool SecondaryTcpServer::HandleOneConnection(
int socket) {
72 AKIpUptaneMes_t *m =
nullptr;
74 asn_codec_ctx_s context{};
76 bool need_reboot =
false;
79 received = recv(socket, buffer.
Tail(), buffer.
TailSpace(), 0);
81 res = ber_decode(&context, &asn_DEF_AKIpUptaneMes, reinterpret_cast<void **>(&m), buffer.
Head(), buffer.
Size());
83 }
while (res.code == RC_WMORE && received > 0);
87 if (res.code != RC_OK) {
93 switch (msg->present()) {
94 case AKIpUptaneMes_PR_getInfoReq: {
98 resp->present(AKIpUptaneMes_PR_getInfoResp);
99 auto r = resp->getInfoResp();
100 SetString(&r->ecuSerial, serial.ToString());
101 SetString(&r->hwId, hw_id.ToString());
102 r->keyType = static_cast<AKIpUptaneKeyType_t>(pk.Type());
103 SetString(&r->key, pk.Value());
105 case AKIpUptaneMes_PR_manifestReq: {
106 std::string manifest = Utils::jsonToStr(impl_.getManifest());
107 resp->present(AKIpUptaneMes_PR_manifestResp);
108 auto r = resp->manifestResp();
109 r->manifest.present = manifest_PR_json;
110 SetString(&r->manifest.choice.json, manifest);
111 LOG_TRACE <<
"Manifest : \n" << manifest;
113 case AKIpUptaneMes_PR_putMetaReq: {
114 auto md = msg->putMetaReq();
117 if (md->director.present == director_PR_json) {
118 meta_pack.director_root = ToString(md->director.choice.json.root);
119 meta_pack.director_targets = ToString(md->director.choice.json.targets);
120 LOG_DEBUG <<
"Received Director repo Root metadata:\n" << meta_pack.director_root;
121 LOG_DEBUG <<
"Received Director repo Targets metadata:\n" << meta_pack.director_targets;
123 LOG_WARNING <<
"Director metadata in unknown format:" << md->director.present;
126 if (md->image.present == image_PR_json) {
127 meta_pack.image_root = ToString(md->image.choice.json.root);
128 meta_pack.image_timestamp = ToString(md->image.choice.json.timestamp);
129 meta_pack.image_snapshot = ToString(md->image.choice.json.snapshot);
130 meta_pack.image_targets = ToString(md->image.choice.json.targets);
131 LOG_DEBUG <<
"Received Image repo Root metadata:\n" << meta_pack.image_root;
132 LOG_DEBUG <<
"Received Image repo Timestamp metadata:\n" << meta_pack.image_timestamp;
133 LOG_DEBUG <<
"Received Image repo Snapshot metadata:\n" << meta_pack.image_snapshot;
134 LOG_DEBUG <<
"Received Image repo Targets metadata:\n" << meta_pack.image_targets;
136 LOG_WARNING <<
"Image repo metadata in unknown format:" << md->image.present;
141 ok = impl_.putMetadata(meta_pack);
143 LOG_WARNING <<
"Rejected metadata push because of security failure" << e.what();
146 resp->present(AKIpUptaneMes_PR_putMetaResp);
147 auto r = resp->putMetaResp();
148 r->result = ok ? AKInstallationResult_success : AKInstallationResult_failure;
150 case AKIpUptaneMes_PR_sendFirmwareReq: {
151 LOG_INFO <<
"Received sendFirmwareReq from Primary.";
152 auto fw = msg->sendFirmwareReq();
153 auto send_firmware_result = impl_.sendFirmware(ToString(fw->firmware));
154 resp->present(AKIpUptaneMes_PR_sendFirmwareResp);
155 auto r = resp->sendFirmwareResp();
156 r->result = send_firmware_result ? AKInstallationResult_success : AKInstallationResult_failure;
158 case AKIpUptaneMes_PR_installReq: {
159 LOG_INFO <<
"Received installReq from Primary.";
160 auto request = msg->installReq();
162 auto install_result = impl_.install(ToString(request->hash));
164 resp->present(AKIpUptaneMes_PR_installResp);
165 auto response_message = resp->installResp();
166 response_message->result = static_cast<AKInstallationResultCode_t>(install_result);
168 if (install_result == data::ResultCode::Numeric::kNeedCompletion) {
173 LOG_ERROR <<
"Unrecognised message type:" << msg->present();
178 if (resp->present() != AKIpUptaneMes_PR_NOTHING) {
180 setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, &optval,
sizeof(
int));
181 asn_enc_rval_t encode_result =
182 der_encode(&asn_DEF_AKIpUptaneMes, &resp->msg_, Asn1SocketWriteCallback, reinterpret_cast<void *>(&socket));
183 if (encode_result.encoded == -1) {
187 setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, &optval,
sizeof(
int));
189 LOG_DEBUG <<
"Not sending a response to message " << msg->present();
192 if (need_reboot && reboot_after_install_) {
193 exit_reason_ = ExitReason::kRebootNeeded;