blob: db2b1cac14ac7cff978362ddacc59da13e35e1d8 [file] [log] [blame]
Zhiyi Zhang46049832020-09-28 17:08:12 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento0dc02012021-11-23 22:55:03 -05002/*
Davide Pesavento9510c912024-02-25 17:50:05 -05003 * Copyright (c) 2017-2024, Regents of the University of California.
Zhiyi Zhang46049832020-09-28 17:08:12 -07004 *
5 * This file is part of ndncert, a certificate management system based on NDN.
6 *
7 * ndncert is free software: you can redistribute it and/or modify it under the terms
8 * of the GNU General Public License as published by the Free Software Foundation, either
9 * version 3 of the License, or (at your option) any later version.
10 *
11 * ndncert is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License along with
16 * ndncert, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * See AUTHORS.md for complete list of ndncert authors and contributors.
19 */
20
Zhiyi Zhangb041d442020-10-22 21:57:11 -070021#include "detail/error-encoder.hpp"
Zhiyi Zhang46049832020-09-28 17:08:12 -070022
Davide Pesavento9510c912024-02-25 17:50:05 -050023#include <ndn-cxx/util/logger.hpp>
Tianyuan Yu13aac732022-03-03 20:59:54 -080024
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040025namespace ndncert::errortlv {
Zhiyi Zhang46049832020-09-28 17:08:12 -070026
Davide Pesavento9510c912024-02-25 17:50:05 -050027NDN_LOG_INIT(ndncert.encode.error);
28
Zhiyi Zhang46049832020-09-28 17:08:12 -070029Block
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040030encodeDataContent(ErrorCode errorCode, const std::string& description)
Zhiyi Zhang46049832020-09-28 17:08:12 -070031{
tylerliu1f480be2020-11-10 13:02:53 -080032 Block response(ndn::tlv::Content);
Davide Pesavento0dc02012021-11-23 22:55:03 -050033 response.push_back(ndn::makeNonNegativeIntegerBlock(tlv::ErrorCode, static_cast<size_t>(errorCode)));
34 response.push_back(ndn::makeStringBlock(tlv::ErrorInfo, description));
Zhiyi Zhang46049832020-09-28 17:08:12 -070035 response.encode();
36 return response;
37}
38
Zhiyi Zhangaafc55e2020-09-28 17:54:48 -070039std::tuple<ErrorCode, std::string>
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040040decodefromDataContent(const Block& block)
Zhiyi Zhang46049832020-09-28 17:08:12 -070041{
Tianyuan Yu13aac732022-03-03 20:59:54 -080042 try {
43 block.parse();
Davide Pesavento6a625d82023-02-24 03:38:06 -050044
Tianyuan Yu13aac732022-03-03 20:59:54 -080045 int codeCount = 0;
46 int infoCount = 0;
47 int otherCriticalCount = 0;
Davide Pesavento6a625d82023-02-24 03:38:06 -050048 ErrorCode error = ErrorCode::NO_ERROR;
Tianyuan Yu13aac732022-03-03 20:59:54 -080049 std::string errorInfo;
50 for (const auto& item : block.elements()) {
51 if (item.type() == tlv::ErrorCode) {
Davide Pesavento6a625d82023-02-24 03:38:06 -050052 error = ndn::readNonNegativeIntegerAs<ErrorCode>(block.get(tlv::ErrorCode));
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040053 codeCount++;
Tianyuan Yu13aac732022-03-03 20:59:54 -080054 }
55 else if (item.type() == tlv::ErrorInfo) {
56 errorInfo = readString(block.get(tlv::ErrorInfo));
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040057 infoCount++;
Tianyuan Yu13aac732022-03-03 20:59:54 -080058 }
59 else if (ndn::tlv::isCriticalType(item.type())) {
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040060 otherCriticalCount++;
Tianyuan Yu13aac732022-03-03 20:59:54 -080061 }
62 else {
Davide Pesavento6a625d82023-02-24 03:38:06 -050063 // ignore
Tianyuan Yu13aac732022-03-03 20:59:54 -080064 }
65 }
Davide Pesavento6a625d82023-02-24 03:38:06 -050066
Tianyuan Yu13aac732022-03-03 20:59:54 -080067 if (codeCount == 0 && infoCount == 0) {
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040068 return {ErrorCode::NO_ERROR, ""};
Tianyuan Yu13aac732022-03-03 20:59:54 -080069 }
70 if (codeCount != 1 || infoCount != 1) {
71 NDN_THROW(std::runtime_error("Error TLV contains " + std::to_string(codeCount) + " error code(s) and " +
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040072 std::to_string(infoCount) + " error info(s), instead of expected 1 time each."));
Tianyuan Yu13aac732022-03-03 20:59:54 -080073 }
74 if (otherCriticalCount > 0) {
Davide Pesavento6a625d82023-02-24 03:38:06 -050075 NDN_THROW(std::runtime_error("Unknown critical TLV type in error packet"));
Tianyuan Yu13aac732022-03-03 20:59:54 -080076 }
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040077 return {error, errorInfo};
78 }
79 catch (const std::exception& e) {
80 NDN_LOG_ERROR("Exception in error message decoding: " << e.what());
81 return {ErrorCode::NO_ERROR, ""};
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070082 }
tylerliu36d97f52020-09-30 22:32:54 -070083}
84
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040085} // namespace ndncert::errortlv