* This file is part of the openHiTLS project.
*
* openHiTLS is licensed under the Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <stdbool.h>
#include <semaphore.h>
#include <string.h>
#include "channel_res.h"
#include "handle_cmd.h"
#include "tls_res.h"
#include "control_channel.h"
#include "logger.h"
#include "lock.h"
#include "rpc_func.h"
#include "hlt_type.h"
#include "hlt.h"
#include "process.h"
#define DOMAIN_PATH_LEN (128)
#define SUCCESS 0
#define ERROR (-1)
#define ASSERT_RETURN(condition, log) \
do { \
if (!(condition)) { \
LOG_ERROR(log); \
return ERROR; \
} \
} while (0)
int IsFeedbackResult(ControlChannelRes *channelInfo)
{
int i, ret;
ControlChannelBuf dataBuf = {0};
OsLock(channelInfo->sendBufferLock);
if (channelInfo->sendBufferNum == 0) {
OsUnLock(channelInfo->sendBufferLock);
return SUCCESS;
}
i = 0;
while (channelInfo->sendBufferNum > 0) {
size_t len = strlen((char *)channelInfo->sendBuffer[i]);
if (len >= CONTROL_CHANNEL_MAX_MSG_LEN) {
LOG_ERROR("MemCpy Error");
OsUnLock(channelInfo->sendBufferLock);
return ERROR;
}
memcpy(dataBuf.data, channelInfo->sendBuffer[i], len + 1);
dataBuf.dataLen = len;
LOG_DEBUG("Remote Process Send Result %s", dataBuf.data);
ret = ControlChannelWrite(channelInfo->sockFd, channelInfo->peerDomainPath, &dataBuf);
if (ret != 0) {
LOG_ERROR("ControlChannelWrite Error, Msg is %s, ret is %d\n", dataBuf.data, ret);
OsUnLock(channelInfo->sendBufferLock);
return ERROR;
}
LOG_DEBUG("Remote Process Send Result %s Success", dataBuf.data);
channelInfo->sendBufferNum--;
i++;
}
OsUnLock(channelInfo->sendBufferLock);
return SUCCESS;
}
void FreeThreadRes(pthread_t *threadList, int threadNum)
{
for (int i = 0; i < threadNum; i++) {
pthread_cancel(threadList[i]);
pthread_join(threadList[i], NULL);
}
return;
}
void ThreadExcuteCmd(void *param)
{
CmdData cmdData = {0};
if (sizeof(CmdData) > sizeof(cmdData)) {
free(param);
return;
}
memcpy(&cmdData, (CmdData *)param, sizeof(CmdData));
free(param);
ControlChannelRes *channelInfo = GetControlChannelRes();
(void)ExecuteCmd(&cmdData);
PushResultToChannelSendBuffer(channelInfo, cmdData.result);
return;
}
int main(int argc, char **argv)
{
int ret, sctpFd = -1;
ControlChannelRes* channelInfo = NULL;
ControlChannelBuf dataBuf;
CmdData exitCmdData = {0};
CmdData* cmdData = NULL;
Process* process = NULL;
pid_t ppid = atoi(argv[4]);
(void)ppid;
setbuf(stdout, NULL);
LOG_DEBUG("argv value is %d", argc);
ret = InitProcess();
ASSERT_RETURN(ret == SUCCESS, "InitProcess Error");
process = GetProcess();
process->remoteFlag = 1;
process->tlsType = atoi(argv[1]);
if (strlen(argv[2]) >= DOMAIN_PATH_LEN) {
ASSERT_RETURN(0, "memcpy process->srcDomainPath Error");
}
memcpy(process->srcDomainPath, argv[2], strlen(argv[2]) + 1);
if (strlen(argv[3]) >= DOMAIN_PATH_LEN) {
ASSERT_RETURN(0, "memcpy process->peerDomainPath Error");
}
memcpy(process->peerDomainPath, argv[3], strlen(argv[3]) + 1);
ret = HLT_LibraryInit(process->tlsType);
ASSERT_RETURN(ret == SUCCESS, "HLT_TlsRegCallback Error");
ret = InitTlsResList();
ASSERT_RETURN(ret == SUCCESS, "InitTlsResList Error");
ret = InitControlChannelRes(process->srcDomainPath, strlen(process->srcDomainPath),
process->peerDomainPath, strlen(process->peerDomainPath));
ASSERT_RETURN(ret == SUCCESS, "ChannelInfoInit Error");
channelInfo = GetControlChannelRes();
ret = ControlChannelInit(channelInfo);
ASSERT_RETURN(ret == SUCCESS, "ControlChannelInit Error");
LOG_DEBUG("Create Remote Process Successful");
PushResultToChannelSendBuffer(channelInfo, "0|HEART");
while (1) {
if (kill(ppid, 0) != 0) {
LOG_DEBUG("\nthe parent process [%u] does not exist, I want to exist\n", ppid);
break;
}
ret = ControlChannelRead(channelInfo->sockFd, &dataBuf);
if (ret == 0) {
LOG_DEBUG("Remote Process Rcv Cmd Is: %s", dataBuf.data);
cmdData = (CmdData*)malloc(sizeof(CmdData));
if (cmdData == NULL) {
LOG_ERROR("Malloc cmdData Error");
break;
}
ret = ParseCmdFromBuf(&dataBuf, cmdData);
if (ret != SUCCESS) {
LOG_ERROR("ParseCmdFromBuf Error ...");
free(cmdData);
break;
}
if (strncmp((char *)cmdData->funcId, "HLT_RpcProcessExit", strlen("HLT_RpcProcessExit")) == 0) {
sctpFd = atoi((char *)cmdData->paras[0]);
(void)snprintf((char *)exitCmdData.result, sizeof(exitCmdData.result), "%s|%s|%d",
cmdData->id, cmdData->funcId, sctpFd);
PushResultToChannelSendBuffer(channelInfo, exitCmdData.result);
free(cmdData);
break;
}
ThreadExcuteCmd(cmdData);
}
ret = IsFeedbackResult(channelInfo);
if (ret != 0) {
break;
}
}
LOG_DEBUG("Process Return");
(void)IsFeedbackResult(channelInfo);
FreeControlChannelRes();
FreeTlsResList();
FreeProcess();
if (sctpFd > 0) {
close(sctpFd);
}
return SUCCESS;
}