Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include "tsd_version_verify.h"
12 : #include "tsd_log.h"
13 : namespace tsd {
14 : namespace {
15 : // 如果修改了涉及tsdclient和tsdaemon需要配合的特性,则需要在此map中增加对应的特性信息,防止client或server单独升级导致运行结果不可控
16 : // map的关键字是建立通信的类型,值是当前版本影响兼容性所新增、修改、删除的特性列表
17 : // 每次更新版本号的时候,可以清空map,该map仅用于存放同一版本内的特性变化
18 : // 示例 {HDCMessage::TSD_START_PROC_MSG, {"feature1","feature2"}}
19 : // 由于1,2包和3-8包存在新老版本使用问题,兼容校验是feature_list字符串比较,所以这里的字符串千万不能更改,更改会出现新老版本兼容性问题
20 : std::map<HDCMessage::MsgType, std::set<std::string>> g_tsdFeatureList = {
21 : {HDCMessage::TSD_CHECK_PACKAGE, {"check before send aicpu package"}},
22 : {HDCMessage::TSD_START_QS_MSG, {"check before send open qs message"}},
23 : {HDCMessage::TSD_CHECK_PACKAGE_RETRY, {"get check code retry"}},
24 : };
25 : // 版本号不能修改,修改会导致client和server版本不一致。
26 : // 新的server端虽然支持TSD_CHECK_PACKAGE消息,但是旧的client会认为不支持,无法发送。
27 : constexpr uint32_t TSD_VERSION = 1230U;
28 : } // namespace
29 :
30 : /**
31 : * @ingroup VersionVerify
32 : * @param [in] msg : message send by client
33 : * @brief add version info to message which client will send to server
34 : */
35 93 : void VersionVerify::SetVersionInfo(HDCMessage& msg) const
36 : {
37 : // client need send it's version info to server once
38 93 : HDCMessage::VersionInfo* const verInfo = msg.mutable_version_info();
39 93 : TSD_RUN_INFO("VersionVerify: send client version to server");
40 93 : if (verInfo == nullptr) {
41 0 : return;
42 : }
43 93 : verInfo->set_version(TSD_VERSION);
44 372 : for (const auto& iter : g_tsdFeatureList) {
45 279 : HDCMessage::VersionInfo::FeatureList* const fl = verInfo->add_feature_list();
46 279 : if (fl == nullptr) {
47 0 : return;
48 : }
49 279 : fl->set_msg_type(iter.first);
50 279 : std::string serializedFeatures; // for log print
51 558 : for (const std::string& feature : iter.second) {
52 279 : serializedFeatures = serializedFeatures + feature;
53 279 : fl->add_feature(feature);
54 : }
55 279 : TSD_INFO("send feature_info:{msgType:%u, features:{%s}}", iter.first, serializedFeatures.c_str());
56 279 : }
57 : }
58 :
59 : /**
60 : * @ingroup VersionVerify
61 : * @param [in] peerVersionInfo : client version info
62 : * @brief check whether client and server can establish communication
63 : */
64 38 : bool VersionVerify::PeerVersionCheck(const HDCMessage::VersionInfo& peerVersionInfo)
65 : {
66 38 : if (peerVersionInfo.version() <= 0U) {
67 1 : TSD_ERROR("VersionVerify: Get peer version[%u] is invalid", peerVersionInfo.version());
68 1 : return false;
69 : }
70 37 : TSD_RUN_INFO(
71 : "VersionVerify: Check client version info, server[%u], client[%u]", peerVersionInfo.version(), TSD_VERSION);
72 37 : ParseVersionInfo(peerVersionInfo);
73 37 : peerVersion_ = static_cast<uint32_t>(peerVersionInfo.version());
74 37 : return peerVersion_ == TSD_VERSION;
75 : }
76 :
77 : /**
78 : * @ingroup VersionVerify
79 : * @param [in] peerVersionInfo : client version info
80 : * @brief parse and save version info send from client
81 : */
82 75 : void VersionVerify::ParseVersionInfo(const HDCMessage::VersionInfo& peerVersionInfo)
83 : {
84 297 : for (int32_t i = 0; i < peerVersionInfo.feature_list_size(); i++) {
85 222 : const HDCMessage::VersionInfo::FeatureList& peerFeatureList = peerVersionInfo.feature_list(i);
86 222 : std::set<std::string> feature;
87 444 : for (int32_t j = 0; j < peerFeatureList.feature_size(); j++) {
88 222 : (void)feature.insert(peerFeatureList.feature(j));
89 : }
90 222 : peerFeatureList_[peerFeatureList.msg_type()] = feature;
91 222 : }
92 75 : TSD_RUN_INFO("VersionVerify: pass client version info success");
93 75 : }
94 :
95 : /**
96 : * @ingroup VersionVerify
97 : * @param [in] msgType : communication type
98 : * @param [in] peer_version_info : client version info
99 : * @brief check whether this type of communication can be understood by server
100 : */
101 167 : bool VersionVerify::SpecialFeatureCheck(const HDCMessage::MsgType& msgType)
102 : {
103 : // test message need not check
104 167 : if ((msgType == HDCMessage::TEST_HDC_SEND) || (msgType == HDCMessage::TEST_HDC_RSP)) {
105 55 : return true;
106 : }
107 : // msgType only need check once
108 112 : const auto alreadyCheckedIter = alreadyCheckedList_.find(msgType);
109 112 : if (alreadyCheckedIter != alreadyCheckedList_.end()) {
110 42 : return alreadyCheckedIter->second;
111 : }
112 : // 该特性之前的消息类型都没有加到VersionInfo里面,此类消息不做限制
113 : // 如果当前type在client和server的VersionInfo里面都不在,则认为是当前版本之前定义的消息类型,不做限制
114 70 : const auto tsdFeatureIter = g_tsdFeatureList.find(msgType);
115 70 : const auto peerFeatureIter = peerFeatureList_.find(msgType);
116 70 : if ((tsdFeatureIter == g_tsdFeatureList.end()) && (peerFeatureIter == peerFeatureList_.end())) {
117 63 : TSD_RUN_INFO("VersionVerify: previous type[%u], supported", static_cast<uint32_t>(msgType));
118 63 : (void)alreadyCheckedList_.insert(std::make_pair(msgType, true));
119 63 : return true;
120 : }
121 : // 当且仅当client和server端的VersionInfo都存在该msgType(新增的),并且对应的feature_list相同才认为是可以通信的版本
122 7 : if ((tsdFeatureIter != g_tsdFeatureList.end()) && (peerFeatureIter != peerFeatureList_.end())) {
123 18 : std::map<std::set<std::string>, int32_t> compareList = {{tsdFeatureIter->second, 1}};
124 6 : if (compareList.find(peerFeatureIter->second) != compareList.end()) {
125 5 : TSD_RUN_INFO("VersionVerify: new type[%u], supported", static_cast<uint32_t>(msgType));
126 5 : (void)alreadyCheckedList_.insert(std::make_pair(msgType, true));
127 5 : return true;
128 : }
129 6 : }
130 2 : TSD_RUN_INFO(
131 : "VersionVerify: msgType[%u] is not supported, please check and update your software",
132 : static_cast<uint32_t>(msgType));
133 2 : (void)alreadyCheckedList_.insert(std::make_pair(msgType, false));
134 2 : return false;
135 6 : }
136 : } // namespace tsd
|