diff --git a/migcvm-agent/CMakeLists.txt b/migcvm-agent/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..1c1ee9c0b2d6679d6a4759f939b073a01bec6ae4 --- /dev/null +++ b/migcvm-agent/CMakeLists.txt @@ -0,0 +1,99 @@ +cmake_minimum_required(VERSION 3.10) +project(MIGVM_Agent) + +# Set build type +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") +endif() + +message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") + +# Set C standard +set(CMAKE_C_STANDARD 99) +set(CMAKE_C_STANDARD_REQUIRED ON) + +# Use host compiler +message(STATUS "Using host compiler") + +# Add executable +# Main executable +add_executable(migvm_agent + migvm_agent.c + migcvm_tsi/migcvm_tsi.c + socket_agent/host_socket_agent.c +) + +# Debug tool +add_executable(socket-send + debug/socket-send.c +) +target_include_directories(socket-send PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/socket_agent +) + +add_executable(tsi-test + debug/tsi-test.c + migcvm_tsi/migcvm_tsi.c +) +target_include_directories(tsi-test PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/migcvm_tsi +) + +# Build debug tool in debug mode +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + add_dependencies(migvm_agent socket-send tsi-test) +endif() + +# Include directories +target_include_directories(migvm_agent PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/migcvm_tsi + ${CMAKE_CURRENT_SOURCE_DIR}/socket_agent +) + +# Common compile options +target_compile_options(migvm_agent PRIVATE + $<$:-O0 -g3 -DDEBUG> + $<$>:-O2 -DNDEBUG> + -Wall + -Wextra + -Werror + -fPIC +) + +target_compile_options(socket-send PRIVATE + -g3 -O0 -DDEBUG + -Wall + -Wextra + -fPIC +) + +target_compile_options(tsi-test PRIVATE + -g3 -O0 -DDEBUG + -Wall + -Wextra + -fPIC +) + +# General Compiler Options +target_compile_options(migvm_agent PRIVATE + -Wall + -Wextra + -Werror + -fPIC +) + +target_link_options(migvm_agent PRIVATE + -Wl,--no-undefined +) + +# Link libraries +target_link_libraries(migvm_agent PRIVATE + pthread +) + +# Install target +install(TARGETS migvm_agent + RUNTIME DESTINATION bin +) + diff --git a/migcvm-agent/README.md b/migcvm-agent/README.md new file mode 100644 index 0000000000000000000000000000000000000000..77f042d0b557237241be682b79d69868a8823c75 --- /dev/null +++ b/migcvm-agent/README.md @@ -0,0 +1,121 @@ +# MIGVM + +## +MIGVMTSI + +## +1. +2. +```bash +chmod +x build.sh +./build.sh +``` + +`build``migvm_agent` + +### +`--debug` +```bash +./build.sh --debug +``` + +socket-send +```bash +./build.sh --build-debug-tool +``` + +## + +```bash +./build/migvm_agent +``` + +## +``` +. + CMakeLists.txt # CMake + build.sh # + migvm_agent.c # + debug/ # + socket-send.c # + tsi-test.c # TSI + migcvm_tsi/ # TSI + migcvm_tsi.c + tsi.h + socket_agent/ # + host_socket_agent.c + socket_agent.h +``` + +## +DH +1. xxxxxx + +## +- CMake (>= 3.10) +- GNU Make +- C (GCCClang) + +--- + +# MIGVM Agent + +## Overview +The MIGVM Agent is a virtual machine migration agent that provides socket communication and TSI (Trusted Service Interface) capabilities. + +## Build Instructions +1. Clone the repository +2. Run the build script: +```bash +chmod +x build.sh +./build.sh +``` + +The executable will be generated in the `build` directory as `migvm_agent`. + +### Debug Mode +To build in debug mode, add the `--debug` parameter: +```bash +./build.sh --debug +``` + +Debug tool (socket-send) can be built separately: +```bash +./build.sh --build-debug-tool +``` + +## Run Instructions +Execute the agent with: +```bash +./build/migvm_agent +``` + +## Directory Structure +``` +. + CMakeLists.txt # CMake configuration + build.sh # Build automation script + migvm_agent.c # Main application + debug/ # Debug tools + socket-send.c # Socket test tool + tsi-test.c # TSI test tool + migcvm_tsi/ # TSI implementation + migcvm_tsi.c + tsi.h + socket_agent/ # Socket communication + host_socket_agent.c + socket_agent.h +``` + +## Secure Communication +The agent uses DH key exchange to establish secure channels: +1. xxxxxx + +## Dependencies +- CMake (>= 3.10) +- GNU Make +- C compiler (GCC or Clang) + +## License +This project is licensed under the MIT License. + diff --git a/migcvm-agent/build.sh b/migcvm-agent/build.sh new file mode 100644 index 0000000000000000000000000000000000000000..101be5d54cf63531927eb4f0c17f81df71157e0c --- /dev/null +++ b/migcvm-agent/build.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +# +BUILD_TYPE="Release" +BUILD_DEBUG_TOOL=false +CLEAN=false + +for arg in "$@"; do + case $arg in + --debug) + BUILD_TYPE="Debug" + ;; + --build-debug-tool) + BUILD_DEBUG_TOOL=true + ;; + --clean) + CLEAN=true + ;; + esac +done + +# +if [[ $CLEAN == true ]]; then + echo "Cleaning build directory..." + rm -rf build +fi + +# +mkdir -p build +cd build || exit + +# cmake +echo "Running cmake with build type: ${BUILD_TYPE}..." +cmake -DCMAKE_BUILD_TYPE=${BUILD_TYPE} .. || { + echo "CMake failed" + exit 1 +} + +# +echo "Building project..." +if [[ $BUILD_DEBUG_TOOL == true ]]; then + echo "Building debug tool only..." + make socket-send tsi_test || { + echo "Debug tool build failed" + exit 1 + } + echo "Debug tool built successfully! Executable is located at: build/socket-send" +elif [[ $BUILD_TYPE == "Debug" ]]; then + echo "Building in debug mode (both main agent and debug tool)..." + make migvm_agent socket-send tsi-test || { + echo "Build failed" + exit 1 + } + echo "Build successful! Executables are located at: build/migvm_agent and build/socket-send" +else + make migvm_agent || { + echo "Build failed" + exit 1 + } + echo "Build successful! Executable is located at: build/migvm_agent" +fi + diff --git a/migcvm-agent/debug/socket-send.c b/migcvm-agent/debug/socket-send.c new file mode 100644 index 0000000000000000000000000000000000000000..175f2107df056a56fc6b29bcc1c47d92e4d4745c --- /dev/null +++ b/migcvm-agent/debug/socket-send.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define TARGET_PORT 9000 +#define TARGET_CID 3 +int main() +{ + int sockfd; + struct sockaddr_vm sa = { + .svm_family = AF_VSOCK, + .svm_cid = TARGET_CID, + .svm_port = TARGET_PORT + }; + + /* setup socket */ + sockfd = socket(AF_VSOCK, SOCK_STREAM, 0); + if (sockfd < 0) { + perror("socket creation failed"); + exit(EXIT_FAILURE); + } + + /* connect server */ + if (connect(sockfd, (struct sockaddr *)&sa, sizeof(sa)) < 0) { + perror("connect failed"); + char errorMessage[256] = {0}; + strerror_r(errno, errorMessage, sizeof(errorMessage)); + printf("failed: %s (errno=%d)\n", errorMessage, errno); + close(sockfd); + exit(EXIT_FAILURE); + } + printf("Connected to VSOCK service at CID=%d, Port=%d\n", sa.svm_cid, sa.svm_port); + + /* send msg */ + const char *msg = "Hello from VSOCK client!"; + if (send(sockfd, msg, strlen(msg), 0) < 0) { + perror("send failed"); + close(sockfd); + exit(EXIT_FAILURE); + } + + printf("Message sent: %s\n", msg); + close(sockfd); + return 0; +} + diff --git a/migcvm-agent/debug/tsi-test.c b/migcvm-agent/debug/tsi-test.c new file mode 100644 index 0000000000000000000000000000000000000000..52190144ee61b3d77bef341cf2c5ffba489a833f --- /dev/null +++ b/migcvm-agent/debug/tsi-test.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "migcvm_tsi.h" +#include "securec.h" + +#define MIN_REQUIRED_ARGS 3 +#define GUEST_RD_BASE 16 +#define GET_MIGRATION_INFO 1 +#define SET_MIGRATION_SLOT 2 + +static int SwitchRequestFunction(TsiCtx *ctx, int functionToTest, + MigrationInfoT *attestInfo, + VirtccaMigvmInfoT *migvmInfo) +{ + int ret; + switch (functionToTest) { + case GET_MIGRATION_INFO: + printf("Testing get_migration_info...\n"); + ret = GetMigrationInfoAndMsk(ctx, migvmInfo, attestInfo); + if (ret == TSI_SUCCESS) { + printf("get_migration_info succeeded\n"); + } else { + printf("get_migration_info failed with error: 0x%08x\n", ret); + TsiFreeCtx(ctx); + return -1; + } + break; + + case SET_MIGRATION_SLOT: + // Parse rd value if provided + printf("Testing set_migration_bind_slot with guestRd=0x%llx...\n", migvmInfo->guestRd); + attestInfo->slotStatus = SLOT_IS_READY; + ret = SetMigrationBindSlotAndMsk(ctx, migvmInfo, attestInfo); + if (ret == TSI_SUCCESS) { + printf("set_migration_bind_slot succeeded\n"); + } else { + printf("set_migration_bind_slot failed with error: 0x%08x\n", ret); + TsiFreeCtx(ctx); + return -1; + } + break; + + default: + printf("Invalid function selection: %d\n", functionToTest); + TsiFreeCtx(ctx); + return -1; + } + return ret; +} + +int main(int argc, char *argv[]) +{ + TsiCtx *ctx = NULL; + VirtccaMigvmInfoT migvmInfo; + MigrationInfoT *attestInfo; + int ret; + unsigned long long guestRd = 0; + int functionToTest = 0; /* 1 for get_migration_info, 2 for set_migration_bind_slot */ + + /* Parse command line arguments */ + if (argc < MIN_REQUIRED_ARGS) { + printf("Usage: %s [rd=]\n", argv[0]); + printf(" function: 1 for get_migration_info, 2 for set_migration_bind_slot\n"); + printf(" rd: guestRd value in hex (e.g., rd=0x20000000)\n"); + return -1; + } + + functionToTest = atoi(argv[1]); + /* Initialize TSI context */ + ctx = TsiNewCtx(); + if (ctx == NULL) { + printf("Failed to create TSI context\n"); + return -1; + } + if (strncmp(argv[MIN_REQUIRED_ARGS - 1], "rd=", MIN_REQUIRED_ARGS) != 0) { + printf("lack of guestRd value for set_migration_bind_slot\n"); + TsiFreeCtx(ctx); + return -1; + } + + guestRd = strtoull(argv[MIN_REQUIRED_ARGS - 1] + MIN_REQUIRED_ARGS, NULL, GUEST_RD_BASE); + printf("using guestRd: 0x%llx\n", guestRd); + + if (memset_s(&migvmInfo, sizeof(migvmInfo), 0, sizeof(migvmInfo)) != 0) { + printf("Failed to initialize migvmInfo\n"); + TsiFreeCtx(ctx); + return -1; + } + migvmInfo.guestRd = guestRd; + attestInfo = (MigrationInfoT *)malloc(sizeof(MigrationInfoT)); + attestInfo->msk = 0x11; + + ret = SwitchRequestFunction(ctx, functionToTest, attestInfo, &migvmInfo); + // Clean up + TsiFreeCtx(ctx); + return ret; +} \ No newline at end of file diff --git a/migcvm-agent/migcvm_tsi/migcvm_tsi.c b/migcvm-agent/migcvm_tsi/migcvm_tsi.c new file mode 100644 index 0000000000000000000000000000000000000000..1f66668810f84c22128414c6e0fcf663b8ef7367 --- /dev/null +++ b/migcvm-agent/migcvm_tsi/migcvm_tsi.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "migcvm_tsi.h" + +TsiCtx *TsiNewCtx(void) +{ + TsiCtx *ctx = calloc(1, sizeof(TsiCtx)); + if (ctx == NULL) { + printf("Failed to allocate TSI context: out of memory\n"); + return NULL; + } + ctx->fd = open("/dev/tsi", O_RDWR | O_CLOEXEC); + if (ctx->fd == -1) { + char errorMessage[256] = {0}; + strerror_r(errno, errorMessage, sizeof(errorMessage)); + printf("Failed to open TSI device: %s (errno=%d)\n", errorMessage, errno); + free(ctx); + return NULL; + } + return ctx; +} + +void TsiFreeCtx(TsiCtx *ctx) +{ + if (ctx == NULL) { + return; + } + if (ctx->fd != -1) { + close(ctx->fd); + } + close(ctx->fd); + free(ctx); +} + +int GetMigrationInfoAndMsk(TsiCtx *ctx, VirtccaMigvmInfoT *migvmInfo, MigrationInfoT *attestInfo) +{ + int ret; + if (ctx == NULL || migvmInfo == NULL || attestInfo == NULL) { + return NULL_INPUT; + } + + migvmInfo->ops = OP_MIGRATE_GET_ATTR; + migvmInfo->size = sizeof(MigrationInfoT); + if (attestInfo == NULL) { + printf("Failed to allocate memory for MigrationInfo: out of memory\n"); + return TSI_ERROR; + } + migvmInfo->migInfo = attestInfo; + + ret = ioctl(ctx->fd, TMM_GET_MIGRATION_INFO, migvmInfo); + if (ret != 0) { + char errorMessage[256] = {0}; + strerror_r(errno, errorMessage, sizeof(errorMessage)); + printf("Failed to get migration info: %s (errno=%d)\n", errorMessage, errno); + free(attestInfo); + return TSI_ERROR; + } + + if (attestInfo->msk) { + printf("the local msk is 0x%lx\n", attestInfo->msk); + } else { + printf("the msk is not set\n"); + } + + if (attestInfo->isSrc) { + printf("This is a source VM.\n"); + } else { + printf("This is a destination VM.\n"); + } + free(attestInfo); + return TSI_SUCCESS; +} + +int SetMigrationBindSlotAndMsk(TsiCtx *ctx, VirtccaMigvmInfoT *migvmInfo, MigrationInfoT *attestInfo) +{ + int ret; + if (ctx == NULL || migvmInfo == NULL || attestInfo == NULL) { + return NULL_INPUT; + } + + migvmInfo->size = sizeof(MigrationInfoT); + migvmInfo->ops = OP_MIGRATE_SET_SLOT; + migvmInfo->migInfo = attestInfo; + + ret = ioctl(ctx->fd, TMM_GET_MIGRATION_INFO, migvmInfo); + if (ret != 0) { + printf("Failed to get migration info. errno: %d\n", errno); + return TSI_ERROR; + } + + return TSI_SUCCESS; +} diff --git a/migcvm-agent/migcvm_tsi/migcvm_tsi.h b/migcvm-agent/migcvm_tsi/migcvm_tsi.h new file mode 100644 index 0000000000000000000000000000000000000000..e650f1bfbd427fbbfa9a433268f67577a160f226 --- /dev/null +++ b/migcvm-agent/migcvm_tsi/migcvm_tsi.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. + */ + +#ifndef MIGCVM_TSI_H +#define MIGCVM_TSI_H +#include +#include + +#define TSI_MAGIC 'T' +#define TSI_SUCCESS 0 + +/* Measurement Related Defination */ +#define TMI_HASH_ALGO_SHA256 0 +#define TMI_HASH_ALGO_SHA512 1 +#define TMI_HASH_ALGO_SM3 2 + +#ifndef HASH_ALGO +#define HASH_ALGO +enum HashAlgo { + HASH_ALGO_SHA256 = TMI_HASH_ALGO_SHA256, + HASH_ALGO_SHA512 = TMI_HASH_ALGO_SHA512, + HASH_ALGO_SM3 = TMI_HASH_ALGO_SM3, +}; +#endif + +enum SlotStatus { + SLOT_IS_EMPTY = 0, + SLOT_IS_BINDED, + SLOT_IS_READY +}; + +enum TSI_ERROR { + NULL_INPUT = 0x00010001, /* NULL pointer. */ + INVALID_PARAM, /* Invalid param. */ + INSUFFICIENT_BUFFER_LEN, /* Insufficient buffer space. */ + NO_DEVICE_FILE, /* The TSI device file does not exist. */ + TSI_ERROR, /* TSI error. */ +}; + +typedef struct { + int fd; +} TsiCtx; + +/* + * @brief Init ctx. + * @return TSI context + */ +TsiCtx *TsiNewCtx(void); + +/* + * @brief Free ctx. + * @param ctx [IN] TSI context + */ +void TsiFreeCtx(TsiCtx *ctx); + +typedef struct MigrationInfo { + /* Algorithm to use for measurements */ + // enum HashAlgo measurement_algo; + /* cvm measurement */ + // unsigned char measurement[MEASUREMENT_SLOT_NR][MAX_MEASUREMENT_SIZE]; + bool isSrc; + unsigned short slotStatus; + unsigned long msk; +} MigrationInfoT; + +typedef struct VirtccaMigvmInfo { + enum Ops { + OP_MIGRATE_GET_ATTR = 0, + OP_MIGRATE_SET_SLOT + } ops; + MigrationInfoT *migInfo; /* if ops == OP_MIGRATE_GET_ATTR, the size is sizeof(content) */ + unsigned long long guestRd; /* if ops == OP_MIGRATE_SET_SLOT, the size is sizeof(guestRd) */ + unsigned long size; +} VirtccaMigvmInfoT; + +#define TMM_GET_MIGRATION_INFO _IOWR(TSI_MAGIC, 3, struct VirtccaMigvmInfo) + +int GetMigrationInfoAndMsk(TsiCtx *ctx, VirtccaMigvmInfoT *migvmInfo, MigrationInfoT *attestInfo); +int SetMigrationBindSlotAndMsk(TsiCtx *ctx, VirtccaMigvmInfoT *migvmInfo, MigrationInfoT *attestInfo); +#endif \ No newline at end of file diff --git a/migcvm-agent/migvm_agent.c b/migcvm-agent/migvm_agent.c new file mode 100644 index 0000000000000000000000000000000000000000..c3799d857173178ad7e5da734e1c5ee73979e87c --- /dev/null +++ b/migcvm-agent/migvm_agent.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. + */ + +#include +#include +#include +#include "socket_agent/socket_agent.h" + +#define MIGCVM_AGENT_PORT 9000 +#define MIGCVM_CID 3 + +static void CustomHandler(const struct SocketMsg *msg, int connFd) +{ + printf("Custom handling: cmd=%s, payload=0x%llx\n", + msg->cmd, msg->payload); + /* todo: custom handling logic */ + /* multi-thread */ + const char *resp = "ACK"; + /* 1.send msg to dest migcvm */ + /* 2.DH channel setup */ + /* 3.get migration info */ + /* 4.exchange keys */ + /* 5.set_migration_bind_slot */ + write(connFd, resp, strlen(resp) + 1); +} + +int main() +{ + struct SocketAgentCfg cfg = { + .cid = MIGCVM_CID, + .port = MIGCVM_AGENT_PORT, + .backlog = 5 /* the length of the listening queue */ + }; + + int ret = SocketAgentStartWithHandler(&cfg, CustomHandler); /* host socket */ + if (ret != 0) { + fprintf(stderr, "Failed to start socket agent: %d\n", ret); + return ret; + } + + printf("Socket agent started successfully on port %lu with custom handler\n", cfg.port); + return 0; +} + diff --git a/migcvm-agent/socket_agent/host_socket_agent.c b/migcvm-agent/socket_agent/host_socket_agent.c new file mode 100644 index 0000000000000000000000000000000000000000..66efe70c2f857d6497a6c836a3b85eed0cf77d44 --- /dev/null +++ b/migcvm-agent/socket_agent/host_socket_agent.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "socket_agent.h" + +static void DefaultMsgHandler(const struct SocketMsg *msg, int connFd) +{ + printf("Received: cmd='%s', payload=%llu\n", + msg->cmd, (unsigned long long)msg->payload); + const char *resp = "ACK"; + if (write(connFd, resp, strlen(resp) + 1) == -1) { + perror("Failed to send ACK (ignored)"); + } +} + +int SocketAgentStart(const struct SocketAgentCfg *cfg) +{ + return SocketAgentStartWithHandler(cfg, DefaultMsgHandler); +} + +static void CallingHandler(const int listenFd, SocketMsgHandler handler) +{ + while (1) { + int connFd = accept(listenFd, NULL, NULL); + if (connFd < 0) { + perror("accept failed"); + continue; + } + printf("New connection accepted\n"); + + struct SocketMsg msg; + ssize_t bytesRead = read(connFd, &msg, sizeof(msg)); + if (bytesRead == sizeof(msg)) { + if (handler) { + printf("Handling message: cmd='%s', payload=%llu\n", + msg.cmd, (unsigned long long)msg.payload); + handler(&msg, connFd); + } + } else if (bytesRead < 0) { + char errorMessage[256] = {0}; + strerror_r(errno, errorMessage, sizeof(errorMessage)); + printf("read failed: %s (errno=%d)\n", errorMessage, errno); + } else if (bytesRead == 0) { + printf("Connection closed by client\n"); + } else { + printf("Partial message received: %zd/%zu bytes\n", bytesRead, sizeof(msg)); + } + close(connFd); + } +} + +int SocketAgentStartWithHandler(const struct SocketAgentCfg *cfg, + SocketMsgHandler handler) +{ + int listenFd; + char errorMessage[256] = {0}; + struct sockaddr_vm sa = { + .svm_family = AF_VSOCK, + .svm_cid = cfg->cid, + .svm_port = cfg->port + }; + + /* create socket */ + listenFd = socket(AF_VSOCK, SOCK_STREAM, 0); + if (listenFd < 0) { + perror("socket creation failed"); + return -1; + } + + /* allow reuse of local addresses */ + int opt = 1; + if (setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) { + perror("setsockopt failed"); + close(listenFd); + return -1; + } + + printf("Trying to bind: CID=%u, Port=%d\n", sa.svm_cid, sa.svm_port); + if (bind(listenFd, (struct sockaddr *)&sa, sizeof(sa)) < 0) { + strerror_r(errno, errorMessage, sizeof(errorMessage)); + printf("bind failed: %s (errno=%d)\n", errorMessage, errno); + close(listenFd); + return -1; + } + + printf("Successfully bound to port %d\n", sa.svm_port); + if (listen(listenFd, cfg->backlog) < 0) { + strerror_r(errno, errorMessage, sizeof(errorMessage)); + printf("listen failed: %s (errno=%d)\n", errorMessage, errno); + close(listenFd); + return -1; + } + + printf("Listening for VSOCK connections on port %d...\n", sa.svm_port); + CallingHandler(listenFd, handler); + close(listenFd); + return 0; +} \ No newline at end of file diff --git a/migcvm-agent/socket_agent/socket_agent.h b/migcvm-agent/socket_agent/socket_agent.h new file mode 100644 index 0000000000000000000000000000000000000000..ce5e8f95279d05611a2abf94a194500039f49132 --- /dev/null +++ b/migcvm-agent/socket_agent/socket_agent.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. + */ + +#ifndef MIGCVM_SOCKET_AGENT_H +#define MIGCVM_SOCKET_AGENT_H +#include + +#pragma pack(push, 1) + +struct SocketMsg { + char cmd[16]; + unsigned long long payload; +}; +#pragma pack(pop) + +struct SocketAgentCfg { + unsigned long cid; + unsigned long port; + int backlog; +}; + +int SocketAgentStart(const struct SocketAgentCfg *cfg); + +typedef void (*SocketMsgHandler)(const struct SocketMsg *msg, int connFd); + +int SocketAgentStartWithHandler(const struct SocketAgentCfg *cfg, + SocketMsgHandler handler); +#endif \ No newline at end of file