未验证 提交 c4d27182 编写于 作者: S Shengliang Guan 提交者: GitHub

Merge pull request #20332 from taosdata/fix/main_bugfix_wxy

fix: check the compatibility of client version and server version
...@@ -612,6 +612,7 @@ typedef struct { ...@@ -612,6 +612,7 @@ typedef struct {
char user[TSDB_USER_LEN]; char user[TSDB_USER_LEN];
char passwd[TSDB_PASSWORD_LEN]; char passwd[TSDB_PASSWORD_LEN];
int64_t startTime; int64_t startTime;
char sVer[TSDB_VERSION_LEN];
} SConnectReq; } SConnectReq;
int32_t tSerializeSConnectReq(void* buf, int32_t bufLen, SConnectReq* pReq); int32_t tSerializeSConnectReq(void* buf, int32_t bufLen, SConnectReq* pReq);
......
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef _TD_UTIL_VERSION_H_ #ifndef _TD_UTIL_TVERSION_H_
#define _TD_UTIL_VERSION_H_ #define _TD_UTIL_TVERSION_H_
#include "os.h" #include "os.h"
...@@ -25,9 +25,11 @@ extern "C" { ...@@ -25,9 +25,11 @@ extern "C" {
int32_t taosVersionStrToInt(const char *vstr, int32_t *vint); int32_t taosVersionStrToInt(const char *vstr, int32_t *vint);
int32_t taosVersionIntToStr(int32_t vint, char *vstr, int32_t len); int32_t taosVersionIntToStr(int32_t vint, char *vstr, int32_t len);
int32_t taosCheckVersionCompatible(int32_t clientVer, int32_t serverVer, int32_t comparedSegments); int32_t taosCheckVersionCompatible(int32_t clientVer, int32_t serverVer, int32_t comparedSegments);
int32_t taosCheckVersionCompatibleFromStr(const char *pClientVersion, const char *pServerVersion,
int32_t comparedSegments);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /*_TD_UTIL_VERSION_H_*/ #endif /*_TD_UTIL_TVERSION_H_*/
...@@ -1307,6 +1307,7 @@ static SMsgSendInfo* buildConnectMsg(SRequestObj* pRequest) { ...@@ -1307,6 +1307,7 @@ static SMsgSendInfo* buildConnectMsg(SRequestObj* pRequest) {
tstrncpy(connectReq.app, appInfo.appName, sizeof(connectReq.app)); tstrncpy(connectReq.app, appInfo.appName, sizeof(connectReq.app));
tstrncpy(connectReq.user, pObj->user, sizeof(connectReq.user)); tstrncpy(connectReq.user, pObj->user, sizeof(connectReq.user));
tstrncpy(connectReq.passwd, pObj->pass, sizeof(connectReq.passwd)); tstrncpy(connectReq.passwd, pObj->pass, sizeof(connectReq.passwd));
tstrncpy(connectReq.sVer, version, sizeof(connectReq.sVer));
int32_t contLen = tSerializeSConnectReq(NULL, 0, &connectReq); int32_t contLen = tSerializeSConnectReq(NULL, 0, &connectReq);
void* pReq = taosMemoryMalloc(contLen); void* pReq = taosMemoryMalloc(contLen);
......
...@@ -18,10 +18,12 @@ ...@@ -18,10 +18,12 @@
#include "clientLog.h" #include "clientLog.h"
#include "os.h" #include "os.h"
#include "query.h" #include "query.h"
#include "systable.h"
#include "tdatablock.h"
#include "tdef.h" #include "tdef.h"
#include "tglobal.h"
#include "tname.h" #include "tname.h"
#include "tdatablock.h" #include "tversion.h"
#include "systable.h"
static void setErrno(SRequestObj* pRequest, int32_t code) { static void setErrno(SRequestObj* pRequest, int32_t code) {
pRequest->code = code; pRequest->code = code;
...@@ -47,11 +49,11 @@ int32_t genericRspCallback(void* param, SDataBuf* pMsg, int32_t code) { ...@@ -47,11 +49,11 @@ int32_t genericRspCallback(void* param, SDataBuf* pMsg, int32_t code) {
} }
int32_t processConnectRsp(void* param, SDataBuf* pMsg, int32_t code) { int32_t processConnectRsp(void* param, SDataBuf* pMsg, int32_t code) {
SRequestObj *pRequest = acquireRequest(*(int64_t*)param); SRequestObj* pRequest = acquireRequest(*(int64_t*)param);
if (NULL == pRequest) { if (NULL == pRequest) {
goto End; goto End;
} }
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
setErrno(pRequest, code); setErrno(pRequest, code);
tsem_post(&pRequest->body.rspSem); tsem_post(&pRequest->body.rspSem);
...@@ -65,7 +67,7 @@ int32_t processConnectRsp(void* param, SDataBuf* pMsg, int32_t code) { ...@@ -65,7 +67,7 @@ int32_t processConnectRsp(void* param, SDataBuf* pMsg, int32_t code) {
tsem_post(&pRequest->body.rspSem); tsem_post(&pRequest->body.rspSem);
goto End; goto End;
} }
SConnectRsp connectRsp = {0}; SConnectRsp connectRsp = {0};
if (tDeserializeSConnectRsp(pMsg->pData, pMsg->len, &connectRsp) != 0) { if (tDeserializeSConnectRsp(pMsg->pData, pMsg->len, &connectRsp) != 0) {
code = TSDB_CODE_TSC_INVALID_VERSION; code = TSDB_CODE_TSC_INVALID_VERSION;
...@@ -74,6 +76,12 @@ int32_t processConnectRsp(void* param, SDataBuf* pMsg, int32_t code) { ...@@ -74,6 +76,12 @@ int32_t processConnectRsp(void* param, SDataBuf* pMsg, int32_t code) {
goto End; goto End;
} }
if ((code = taosCheckVersionCompatibleFromStr(version, connectRsp.sVer, 2)) != 0) {
setErrno(pRequest, code);
tsem_post(&pRequest->body.rspSem);
goto End;
}
int32_t now = taosGetTimestampSec(); int32_t now = taosGetTimestampSec();
int32_t delta = abs(now - connectRsp.svrTimestamp); int32_t delta = abs(now - connectRsp.svrTimestamp);
if (delta > timestampDeltaLimit) { if (delta > timestampDeltaLimit) {
...@@ -127,14 +135,14 @@ int32_t processConnectRsp(void* param, SDataBuf* pMsg, int32_t code) { ...@@ -127,14 +135,14 @@ int32_t processConnectRsp(void* param, SDataBuf* pMsg, int32_t code) {
tscDebug("0x%" PRIx64 " clusterId:%" PRId64 ", totalConn:%" PRId64, pRequest->requestId, connectRsp.clusterId, tscDebug("0x%" PRIx64 " clusterId:%" PRId64 ", totalConn:%" PRId64, pRequest->requestId, connectRsp.clusterId,
pTscObj->pAppInfo->numOfConns); pTscObj->pAppInfo->numOfConns);
tsem_post(&pRequest->body.rspSem); tsem_post(&pRequest->body.rspSem);
End: End:
if (pRequest) { if (pRequest) {
releaseRequest(pRequest->self); releaseRequest(pRequest->self);
} }
taosMemoryFree(param); taosMemoryFree(param);
taosMemoryFree(pMsg->pEpSet); taosMemoryFree(pMsg->pEpSet);
taosMemoryFree(pMsg->pData); taosMemoryFree(pMsg->pData);
...@@ -166,18 +174,18 @@ int32_t processCreateDbRsp(void* param, SDataBuf* pMsg, int32_t code) { ...@@ -166,18 +174,18 @@ int32_t processCreateDbRsp(void* param, SDataBuf* pMsg, int32_t code) {
struct SCatalog* pCatalog = NULL; struct SCatalog* pCatalog = NULL;
int32_t code = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog); int32_t code = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
STscObj* pTscObj = pRequest->pTscObj; STscObj* pTscObj = pRequest->pTscObj;
SRequestConnInfo conn = {.pTrans = pTscObj->pAppInfo->pTransporter, SRequestConnInfo conn = {.pTrans = pTscObj->pAppInfo->pTransporter,
.requestId = pRequest->requestId, .requestId = pRequest->requestId,
.requestObjRefId = pRequest->self, .requestObjRefId = pRequest->self,
.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp)}; .mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp)};
char dbFName[TSDB_DB_FNAME_LEN]; char dbFName[TSDB_DB_FNAME_LEN];
snprintf(dbFName, sizeof(dbFName) - 1, "%d.%s", pTscObj->acctId, TSDB_INFORMATION_SCHEMA_DB); snprintf(dbFName, sizeof(dbFName) - 1, "%d.%s", pTscObj->acctId, TSDB_INFORMATION_SCHEMA_DB);
catalogRefreshDBVgInfo(pCatalog, &conn, dbFName); catalogRefreshDBVgInfo(pCatalog, &conn, dbFName);
snprintf(dbFName, sizeof(dbFName) - 1, "%d.%s", pTscObj->acctId, TSDB_PERFORMANCE_SCHEMA_DB); snprintf(dbFName, sizeof(dbFName) - 1, "%d.%s", pTscObj->acctId, TSDB_PERFORMANCE_SCHEMA_DB);
catalogRefreshDBVgInfo(pCatalog, &conn, dbFName); catalogRefreshDBVgInfo(pCatalog, &conn, dbFName);
} }
} }
if (pRequest->body.queryFp) { if (pRequest->body.queryFp) {
...@@ -197,7 +205,7 @@ int32_t processUseDbRsp(void* param, SDataBuf* pMsg, int32_t code) { ...@@ -197,7 +205,7 @@ int32_t processUseDbRsp(void* param, SDataBuf* pMsg, int32_t code) {
tDeserializeSUseDbRsp(pMsg->pData, pMsg->len, &usedbRsp); tDeserializeSUseDbRsp(pMsg->pData, pMsg->len, &usedbRsp);
struct SCatalog* pCatalog = NULL; struct SCatalog* pCatalog = NULL;
if (usedbRsp.vgVersion >= 0) { // cached in local if (usedbRsp.vgVersion >= 0) { // cached in local
uint64_t clusterId = pRequest->pTscObj->pAppInfo->clusterId; uint64_t clusterId = pRequest->pTscObj->pAppInfo->clusterId;
int32_t code1 = catalogGetHandle(clusterId, &pCatalog); int32_t code1 = catalogGetHandle(clusterId, &pCatalog);
if (code1 != TSDB_CODE_SUCCESS) { if (code1 != TSDB_CODE_SUCCESS) {
...@@ -289,7 +297,7 @@ int32_t processUseDbRsp(void* param, SDataBuf* pMsg, int32_t code) { ...@@ -289,7 +297,7 @@ int32_t processUseDbRsp(void* param, SDataBuf* pMsg, int32_t code) {
} }
int32_t processCreateSTableRsp(void* param, SDataBuf* pMsg, int32_t code) { int32_t processCreateSTableRsp(void* param, SDataBuf* pMsg, int32_t code) {
if(pMsg == NULL || param == NULL){ if (pMsg == NULL || param == NULL) {
return TSDB_CODE_TSC_INVALID_INPUT; return TSDB_CODE_TSC_INVALID_INPUT;
} }
SRequestObj* pRequest = param; SRequestObj* pRequest = param;
...@@ -344,13 +352,13 @@ int32_t processDropDbRsp(void* param, SDataBuf* pMsg, int32_t code) { ...@@ -344,13 +352,13 @@ int32_t processDropDbRsp(void* param, SDataBuf* pMsg, int32_t code) {
int32_t code = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog); int32_t code = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
catalogRemoveDB(pCatalog, dropdbRsp.db, dropdbRsp.uid); catalogRemoveDB(pCatalog, dropdbRsp.db, dropdbRsp.uid);
STscObj* pTscObj = pRequest->pTscObj; STscObj* pTscObj = pRequest->pTscObj;
SRequestConnInfo conn = {.pTrans = pTscObj->pAppInfo->pTransporter, SRequestConnInfo conn = {.pTrans = pTscObj->pAppInfo->pTransporter,
.requestId = pRequest->requestId, .requestId = pRequest->requestId,
.requestObjRefId = pRequest->self, .requestObjRefId = pRequest->self,
.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp)}; .mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp)};
char dbFName[TSDB_DB_FNAME_LEN]; char dbFName[TSDB_DB_FNAME_LEN];
snprintf(dbFName, sizeof(dbFName) - 1, "%d.%s", pTscObj->acctId, TSDB_INFORMATION_SCHEMA_DB); snprintf(dbFName, sizeof(dbFName) - 1, "%d.%s", pTscObj->acctId, TSDB_INFORMATION_SCHEMA_DB);
catalogRefreshDBVgInfo(pCatalog, &conn, dbFName); catalogRefreshDBVgInfo(pCatalog, &conn, dbFName);
snprintf(dbFName, sizeof(dbFName) - 1, "%d.%s", pTscObj->acctId, TSDB_PERFORMANCE_SCHEMA_DB); snprintf(dbFName, sizeof(dbFName) - 1, "%d.%s", pTscObj->acctId, TSDB_PERFORMANCE_SCHEMA_DB);
...@@ -474,8 +482,9 @@ static int32_t buildShowVariablesRsp(SArray* pVars, SRetrieveTableRsp** pRsp) { ...@@ -474,8 +482,9 @@ static int32_t buildShowVariablesRsp(SArray* pVars, SRetrieveTableRsp** pRsp) {
int32_t len = blockEncode(pBlock, (*pRsp)->data, SHOW_VARIABLES_RESULT_COLS); int32_t len = blockEncode(pBlock, (*pRsp)->data, SHOW_VARIABLES_RESULT_COLS);
blockDataDestroy(pBlock); blockDataDestroy(pBlock);
if(len != rspSize - sizeof(SRetrieveTableRsp)){ if (len != rspSize - sizeof(SRetrieveTableRsp)) {
uError("buildShowVariablesRsp error, len:%d != rspSize - sizeof(SRetrieveTableRsp):%" PRIu64, len, (uint64_t) (rspSize - sizeof(SRetrieveTableRsp))); uError("buildShowVariablesRsp error, len:%d != rspSize - sizeof(SRetrieveTableRsp):%" PRIu64, len,
(uint64_t)(rspSize - sizeof(SRetrieveTableRsp)));
return TSDB_CODE_TSC_INVALID_INPUT; return TSDB_CODE_TSC_INVALID_INPUT;
} }
......
...@@ -3741,6 +3741,7 @@ int32_t tSerializeSConnectReq(void *buf, int32_t bufLen, SConnectReq *pReq) { ...@@ -3741,6 +3741,7 @@ int32_t tSerializeSConnectReq(void *buf, int32_t bufLen, SConnectReq *pReq) {
if (tEncodeCStr(&encoder, pReq->user) < 0) return -1; if (tEncodeCStr(&encoder, pReq->user) < 0) return -1;
if (tEncodeCStrWithLen(&encoder, pReq->passwd, TSDB_PASSWORD_LEN) < 0) return -1; if (tEncodeCStrWithLen(&encoder, pReq->passwd, TSDB_PASSWORD_LEN) < 0) return -1;
if (tEncodeI64(&encoder, pReq->startTime) < 0) return -1; if (tEncodeI64(&encoder, pReq->startTime) < 0) return -1;
if (tEncodeCStr(&encoder, pReq->sVer) < 0) return -1;
tEndEncode(&encoder); tEndEncode(&encoder);
int32_t tlen = encoder.pos; int32_t tlen = encoder.pos;
...@@ -3760,6 +3761,12 @@ int32_t tDeserializeSConnectReq(void *buf, int32_t bufLen, SConnectReq *pReq) { ...@@ -3760,6 +3761,12 @@ int32_t tDeserializeSConnectReq(void *buf, int32_t bufLen, SConnectReq *pReq) {
if (tDecodeCStrTo(&decoder, pReq->user) < 0) return -1; if (tDecodeCStrTo(&decoder, pReq->user) < 0) return -1;
if (tDecodeCStrTo(&decoder, pReq->passwd) < 0) return -1; if (tDecodeCStrTo(&decoder, pReq->passwd) < 0) return -1;
if (tDecodeI64(&decoder, &pReq->startTime) < 0) return -1; if (tDecodeI64(&decoder, &pReq->startTime) < 0) return -1;
// Check the client version from version 3.0.3.0
if (tDecodeIsEnd(&decoder)) {
tDecoderClear(&decoder);
return TSDB_CODE_VERSION_NOT_COMPATIBLE;
}
if (tDecodeCStrTo(&decoder, pReq->sVer) < 0) return -1;
tEndDecode(&decoder); tEndDecode(&decoder);
tDecoderClear(&decoder); tDecoderClear(&decoder);
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include "mndStb.h" #include "mndStb.h"
#include "mndUser.h" #include "mndUser.h"
#include "tglobal.h" #include "tglobal.h"
#include "version.h" #include "tversion.h"
typedef struct { typedef struct {
uint32_t id; uint32_t id;
...@@ -221,11 +221,18 @@ static int32_t mndProcessConnectReq(SRpcMsg *pReq) { ...@@ -221,11 +221,18 @@ static int32_t mndProcessConnectReq(SRpcMsg *pReq) {
char ip[24] = {0}; char ip[24] = {0};
const STraceId *trace = &pReq->info.traceId; const STraceId *trace = &pReq->info.traceId;
if (tDeserializeSConnectReq(pReq->pCont, pReq->contLen, &connReq) != 0) { if ((code = tDeserializeSConnectReq(pReq->pCont, pReq->contLen, &connReq)) != 0) {
terrno = TSDB_CODE_INVALID_MSG; terrno = (-1 == code ? TSDB_CODE_INVALID_MSG : code);
goto _OVER; goto _OVER;
} }
if ((code = taosCheckVersionCompatibleFromStr(connReq.sVer, version, 2)) != 0) {
terrno = code;
goto _OVER;
}
code = -1;
taosIp2String(pReq->info.conn.clientIp, ip); taosIp2String(pReq->info.conn.clientIp, ip);
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CONNECT) != 0) { if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CONNECT) != 0) {
mGError("user:%s, failed to login from %s since %s", pReq->info.conn.user, ip, terrstr()); mGError("user:%s, failed to login from %s since %s", pReq->info.conn.user, ip, terrstr());
......
...@@ -32,13 +32,14 @@ TEST_F(MndTestProfile, 01_ConnectMsg) { ...@@ -32,13 +32,14 @@ TEST_F(MndTestProfile, 01_ConnectMsg) {
connectReq.pid = 1234; connectReq.pid = 1234;
char passwd[] = "taosdata"; char passwd[] = "taosdata";
char secretEncrypt[TSDB_PASSWORD_LEN] = {0}; char secretEncrypt[TSDB_PASSWORD_LEN + 1] = {0};
taosEncryptPass_c((uint8_t*)passwd, strlen(passwd), secretEncrypt); taosEncryptPass_c((uint8_t*)passwd, strlen(passwd), secretEncrypt);
strcpy(connectReq.app, "mnode_test_profile"); strcpy(connectReq.app, "mnode_test_profile");
strcpy(connectReq.db, ""); strcpy(connectReq.db, "");
strcpy(connectReq.user, "root"); strcpy(connectReq.user, "root");
strcpy(connectReq.passwd, secretEncrypt); strcpy(connectReq.passwd, secretEncrypt);
strcpy(connectReq.sVer, version);
int32_t contLen = tSerializeSConnectReq(NULL, 0, &connectReq); int32_t contLen = tSerializeSConnectReq(NULL, 0, &connectReq);
void* pReq = rpcMallocCont(contLen); void* pReq = rpcMallocCont(contLen);
...@@ -66,7 +67,7 @@ TEST_F(MndTestProfile, 01_ConnectMsg) { ...@@ -66,7 +67,7 @@ TEST_F(MndTestProfile, 01_ConnectMsg) {
TEST_F(MndTestProfile, 02_ConnectMsg_InvalidDB) { TEST_F(MndTestProfile, 02_ConnectMsg_InvalidDB) {
char passwd[] = "taosdata"; char passwd[] = "taosdata";
char secretEncrypt[TSDB_PASSWORD_LEN] = {0}; char secretEncrypt[TSDB_PASSWORD_LEN + 1] = {0};
taosEncryptPass_c((uint8_t*)passwd, strlen(passwd), secretEncrypt); taosEncryptPass_c((uint8_t*)passwd, strlen(passwd), secretEncrypt);
SConnectReq connectReq = {0}; SConnectReq connectReq = {0};
...@@ -75,6 +76,7 @@ TEST_F(MndTestProfile, 02_ConnectMsg_InvalidDB) { ...@@ -75,6 +76,7 @@ TEST_F(MndTestProfile, 02_ConnectMsg_InvalidDB) {
strcpy(connectReq.db, "invalid_db"); strcpy(connectReq.db, "invalid_db");
strcpy(connectReq.user, "root"); strcpy(connectReq.user, "root");
strcpy(connectReq.passwd, secretEncrypt); strcpy(connectReq.passwd, secretEncrypt);
strcpy(connectReq.sVer, version);
int32_t contLen = tSerializeSConnectReq(NULL, 0, &connectReq); int32_t contLen = tSerializeSConnectReq(NULL, 0, &connectReq);
void* pReq = rpcMallocCont(contLen); void* pReq = rpcMallocCont(contLen);
......
...@@ -55,7 +55,7 @@ TEST_F(MndTestShow, 02_ShowMsg_InvalidMsgStart) { ...@@ -55,7 +55,7 @@ TEST_F(MndTestShow, 02_ShowMsg_InvalidMsgStart) {
TEST_F(MndTestShow, 03_ShowMsg_Conn) { TEST_F(MndTestShow, 03_ShowMsg_Conn) {
char passwd[] = "taosdata"; char passwd[] = "taosdata";
char secretEncrypt[TSDB_PASSWORD_LEN] = {0}; char secretEncrypt[TSDB_PASSWORD_LEN + 1] = {0};
taosEncryptPass_c((uint8_t*)passwd, strlen(passwd), secretEncrypt); taosEncryptPass_c((uint8_t*)passwd, strlen(passwd), secretEncrypt);
SConnectReq connectReq = {0}; SConnectReq connectReq = {0};
...@@ -64,6 +64,7 @@ TEST_F(MndTestShow, 03_ShowMsg_Conn) { ...@@ -64,6 +64,7 @@ TEST_F(MndTestShow, 03_ShowMsg_Conn) {
strcpy(connectReq.db, ""); strcpy(connectReq.db, "");
strcpy(connectReq.user, "root"); strcpy(connectReq.user, "root");
strcpy(connectReq.passwd, secretEncrypt); strcpy(connectReq.passwd, secretEncrypt);
strcpy(connectReq.sVer, version);
int32_t contLen = tSerializeSConnectReq(NULL, 0, &connectReq); int32_t contLen = tSerializeSConnectReq(NULL, 0, &connectReq);
void* pReq = rpcMallocCont(contLen); void* pReq = rpcMallocCont(contLen);
......
...@@ -89,3 +89,20 @@ int32_t taosCheckVersionCompatible(int32_t clientVer, int32_t serverVer, int32_t ...@@ -89,3 +89,20 @@ int32_t taosCheckVersionCompatible(int32_t clientVer, int32_t serverVer, int32_t
return -1; return -1;
} }
} }
int32_t taosCheckVersionCompatibleFromStr(const char *pClientVersion, const char *pServerVersion,
int32_t comparedSegments) {
int32_t clientVersion = 0;
int32_t serverVersion = 0;
int32_t code = taosVersionStrToInt(pClientVersion, &clientVersion);
if (TSDB_CODE_SUCCESS == code) {
code = taosVersionStrToInt(pServerVersion, &serverVersion);
}
if (TSDB_CODE_SUCCESS == code) {
code = taosCheckVersionCompatible(clientVersion, serverVersion, comparedSegments);
}
if (TSDB_CODE_SUCCESS != code) {
code = terrno;
}
return code;
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册