blob: 09197c9cedc4e43cf492f01f6408fe3e748eb4db [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 Pesavento6a625d82023-02-24 03:38:06 -05003 * Copyright (c) 2017-2023, 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
Tianyuan Yu13aac732022-03-03 20:59:54 -080023NDN_LOG_INIT(ndncert.encode.error);
24
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040025namespace ndncert::errortlv {
Zhiyi Zhang46049832020-09-28 17:08:12 -070026
27Block
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040028encodeDataContent(ErrorCode errorCode, const std::string& description)
Zhiyi Zhang46049832020-09-28 17:08:12 -070029{
tylerliu1f480be2020-11-10 13:02:53 -080030 Block response(ndn::tlv::Content);
Davide Pesavento0dc02012021-11-23 22:55:03 -050031 response.push_back(ndn::makeNonNegativeIntegerBlock(tlv::ErrorCode, static_cast<size_t>(errorCode)));
32 response.push_back(ndn::makeStringBlock(tlv::ErrorInfo, description));
Zhiyi Zhang46049832020-09-28 17:08:12 -070033 response.encode();
34 return response;
35}
36
Zhiyi Zhangaafc55e2020-09-28 17:54:48 -070037std::tuple<ErrorCode, std::string>
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040038decodefromDataContent(const Block& block)
Zhiyi Zhang46049832020-09-28 17:08:12 -070039{
Tianyuan Yu13aac732022-03-03 20:59:54 -080040 try {
41 block.parse();
Davide Pesavento6a625d82023-02-24 03:38:06 -050042
Tianyuan Yu13aac732022-03-03 20:59:54 -080043 int codeCount = 0;
44 int infoCount = 0;
45 int otherCriticalCount = 0;
Davide Pesavento6a625d82023-02-24 03:38:06 -050046 ErrorCode error = ErrorCode::NO_ERROR;
Tianyuan Yu13aac732022-03-03 20:59:54 -080047 std::string errorInfo;
48 for (const auto& item : block.elements()) {
49 if (item.type() == tlv::ErrorCode) {
Davide Pesavento6a625d82023-02-24 03:38:06 -050050 error = ndn::readNonNegativeIntegerAs<ErrorCode>(block.get(tlv::ErrorCode));
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040051 codeCount++;
Tianyuan Yu13aac732022-03-03 20:59:54 -080052 }
53 else if (item.type() == tlv::ErrorInfo) {
54 errorInfo = readString(block.get(tlv::ErrorInfo));
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040055 infoCount++;
Tianyuan Yu13aac732022-03-03 20:59:54 -080056 }
57 else if (ndn::tlv::isCriticalType(item.type())) {
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040058 otherCriticalCount++;
Tianyuan Yu13aac732022-03-03 20:59:54 -080059 }
60 else {
Davide Pesavento6a625d82023-02-24 03:38:06 -050061 // ignore
Tianyuan Yu13aac732022-03-03 20:59:54 -080062 }
63 }
Davide Pesavento6a625d82023-02-24 03:38:06 -050064
Tianyuan Yu13aac732022-03-03 20:59:54 -080065 if (codeCount == 0 && infoCount == 0) {
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040066 return {ErrorCode::NO_ERROR, ""};
Tianyuan Yu13aac732022-03-03 20:59:54 -080067 }
68 if (codeCount != 1 || infoCount != 1) {
69 NDN_THROW(std::runtime_error("Error TLV contains " + std::to_string(codeCount) + " error code(s) and " +
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040070 std::to_string(infoCount) + " error info(s), instead of expected 1 time each."));
Tianyuan Yu13aac732022-03-03 20:59:54 -080071 }
72 if (otherCriticalCount > 0) {
Davide Pesavento6a625d82023-02-24 03:38:06 -050073 NDN_THROW(std::runtime_error("Unknown critical TLV type in error packet"));
Tianyuan Yu13aac732022-03-03 20:59:54 -080074 }
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040075 return {error, errorInfo};
76 }
77 catch (const std::exception& e) {
78 NDN_LOG_ERROR("Exception in error message decoding: " << e.what());
79 return {ErrorCode::NO_ERROR, ""};
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070080 }
tylerliu36d97f52020-09-30 22:32:54 -070081}
82
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040083} // namespace ndncert::errortlv