* Copyright (c) 2022 Huawei Technologies Co.,Ltd.
*
* CBB is licensed under 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.
* -------------------------------------------------------------------------
*
* mes_rpc.h
*
*
* IDENTIFICATION
* src/cm_mes/mes_rpc.h
*
* -------------------------------------------------------------------------
*/
#ifndef __MES_RPC_H__
#define __MES_RPC_H__
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
OCK_RPC_OK = 0,
OCK_RPC_ERR = -1,
OCK_RPC_ERR_INVALID_PARAM = -2,
OCK_RPC_ERR_MISMATCH_MSG_ID = -3,
OCK_RPC_ERR_CONN_UNCONNECTED = -4,
OCK_RPC_ERR_SERIALIZE = -5,
OCK_RPC_ERR_DESERIALIZE = -6,
OCK_RPC_ERR_NO_MEMORY = -7,
OCK_RPC_ERR_RDMA_NOT_ENABLE = -8,
OCK_RPC_ERR_UNPACK_RKEY = -9,
OCK_RPC_ERR_UCP_TAG_SEND = -10,
OCK_RPC_ERR_UCP_TAG_RECV = -11,
OCK_RPC_ERR_UCP_PUT = -12,
OCK_RPC_ERR_UCP_GET = -13,
OCK_RPC_ERR_UNSUPPORT = -14,
OCK_RPC_ERR_SERVICE_EXIST = -15,
OCK_RPC_ERR_ENCRYPT = -16,
OCK_RPC_ERR_DECRYPT = -17,
OCK_RPC_ERR_SINATURE = -18,
OCK_RPC_ERR_UCP_TIMEOUT = -19,
OCK_RPC_ERR_UCP_CLOSE = -20,
OCK_RPC_ERR_CONN_BROKEN = -21,
OCK_RPC_ERR_INVALID_RKEY = -22,
} OckRpcStatus;
#define OCK_RPC_BIT(i) (1ul << (i))
typedef uintptr_t OckRpcServer;
typedef uintptr_t OckRpcClient;
typedef uintptr_t OckRpcClientContext;
typedef uintptr_t OckRpcServerContext;
* @brief Keypass erase function
* @param keypass the memory address of keypass
*/
typedef void (*OckRpcTlsKeypassErase)(char *keypass);
* @brief Get private key file's path and length, and get the keypass
* @param priKeyPath the path of private key
* @param keypass the keypass
* @param erase the erase function
*/
typedef void (*OckRpcTlsGetPrivateKey)(const char **priKeyPath,
char **keypass,
OckRpcTlsKeypassErase *erase);
* @brief Get the certificate file of public key
* @param certPath the path of certificate
*/
typedef void (*OckRpcTlsGetCert)(const char **certPath);
* @brief The cert verify function
* @param x509 the x509 object of CA
* @param crlPath the crl file path
*
* @return -1 for failed, and 1 for success
*/
typedef int (*OckRpcTlsCertVerify)(void *x509, const char *crlPath);
* @brief Get the CA and verify
* @param caPath the path of CA file
* @param crlPath the crl file path
* @param verify the verify function
*/
typedef void (*OckRpcTlsGetCAAndVerify)(const char **caPath, const char **crlPath,
OckRpcTlsCertVerify *verify);
* @brief Message struct.
*/
typedef struct {
void* data;
size_t len;
} OckRpcMessage;
typedef struct {
size_t count;
OckRpcMessage *msgs;
} OckRpcMessageIov;
* @brief Message handler.
*
* User can pass the @b ctx and @b msg to other thread, it will remain valid until
* @ref OckRpcServerCleanupCtx is called. After calling the @ref OckRpcServerReply,
* user need to call @ref OckRpcServerCleanupCtx to release @b ctx. The lifetime
* of the memory that @b msg points to is same as @b ctx. So after invoking
* @ref OckRpcServerCleanupCtx, the @b msg is freed and can not be used anymore.
*/
typedef void(*OckRpcMsgHandler)(OckRpcServerContext ctx, OckRpcMessage msg);
* @brief RPC call completion callback.
*
* @b status is the result of the communication call and @b arg is specified by user.
*/
typedef void(*OckRpcDoneCallback)(OckRpcStatus status, void* arg);
* @brief User-defined server context creation and clearance functions.
*
* The server default context builder and cleanup functions use the glibc new/delete,
* Sometimes its performance cannot meet the requirements of the current scenario, users
* can use customized functions to accelerate the performance.
*/
typedef OckRpcServerContext (*OckRpcServerCtxBuilderHandler)(OckRpcServer server);
typedef void (*OckRpcServerCtxCleanupHandler)(OckRpcServer server, OckRpcServerContext ctx);
* @brief Default server-context builder by static thread local variable
*
* @note If user use those server context handlers, please make sure that every context
* must be cleanup before @ref OckRpcMsgHandler return, you can not use server context
* in other thread.
*/
OckRpcServerContext OckRpcServerCtxBuilderThreadLocal(OckRpcServer server);
void OckRpcServerCtxCleanupThreadLocal(OckRpcServer server, OckRpcServerContext ctx);
* @brief RPC Service.
*
* Each service is a kind of message processing object.
*/
typedef struct {
uint16_t id;
OckRpcMsgHandler handler;
} OckRpcService;
* @brief RPC call completion handle.
*
* This structure should be allocated by the user and can be passed to communication
* primitives, such as @ref OckRpcClientCall. When the structure object is passed
* in, the communication routine changes to asynchronous mode. And if the routine
* returns success, the actual completion result will be notified through this callback.
*/
typedef struct {
OckRpcDoneCallback cb;
void* arg;
} OckRpcCallDone;
typedef struct {
const char* key;
const char* value;
} RpcConfigPair;
typedef struct {
int size;
RpcConfigPair *pairs;
} RpcConfigs;
typedef enum {
OCK_RPC_CONFIG_USE_RPC_CONFIGS = OCK_RPC_BIT(0),
OCK_RPC_CONFIG_USE_SERVER_CTX_BUILD = OCK_RPC_BIT(1),
OCK_RPC_CONFIG_USE_SSL_CALLBACK = OCK_RPC_BIT(2),
} OckRpcCreateConfigMask;
typedef struct {
uint64_t mask;
RpcConfigs configs;
OckRpcServerCtxBuilderHandler serverCtxbuilder;
OckRpcServerCtxCleanupHandler serverCtxCleanup;
* Set SSL handler, must enable OCK_RPC_CONFIG_USE_SSL_CALLBACK
*
* In Server side getCert and getPriKey can't be nullptr
* In Client side getCaAndVerify can't be nullptr
*/
OckRpcTlsGetCAAndVerify getCaAndVerify;
OckRpcTlsGetCert getCert;
OckRpcTlsGetPrivateKey getPriKey;
} OckRpcCreateConfig;
typedef struct {
uint64_t mask;
OckRpcClient client;
* It is recommended that the client context be reused for the high performance, so users can call
* @ref OckRpcClientCreateCtx() for alloc context.
*
* @note But for convenience that user can set it to NULL.
*/
OckRpcClientContext context;
uint16_t msgId;
OckRpcMessageIov reqIov;
* There are 3 methods to use rspIov
* 1. Don't recv response, so set the rspIov.count to 0;
* 2. Recv the response but don't know the length of response, so set the rspIov.count to 1 and
* set the first msg in rspIov.msgs to {.data = NULL, .len = 0}, finally RPC will put response
* to rspIov.msgs[0], and user need to free this memory in rspIov.msgs[0].data.
* 3. Know the length of response
*/
OckRpcMessageIov rspIov;
OckRpcCallDone *done;
} OckRpcClientCallParams;
typedef enum {
OCK_RPC_CLIENT_CALL_DEFAULT = 0,
} OckRpcClientCallParamMask;
* @brief Create a rpc server with rpc create config
*
* Only create a server object, does not start listening.
*
* @param ip Server IP.
* @param port Server port.
* @param server Created server.
* @param config Server create configurations, please configure the corresponding mask.
*
* @return OCK_RPC_OK for success and others for failure.
*/
OckRpcStatus OckRpcServerCreateWithCfg(const char* ip, uint16_t port, OckRpcServer* server,
OckRpcCreateConfig *configs);
* @brief Add service.
*
* Register the message handling method to the server. When a message with this
* ID is received, the registered message handler is called.
*
* @param server Server handle.
* @param service Message processing object.
* @return OCK_RPC_OK for success and others for failure.
*/
OckRpcStatus OckRpcServerAddService(OckRpcServer server, OckRpcService* service);
* @brief Start the server.
*
* This is not a blocking routine, it will return after listening the binded address.
*
* @param server Server handle returned by @ref OckRpcServerCreate .
* @return OCK_RPC_OK for success and others for failure.
*/
OckRpcStatus OckRpcServerStart(OckRpcServer server);
* @brief Stop and destroy the server.
*
* After this routine, the server handle can not be used again.
*
* @param server Server handle returned by @ref OckRpcServerCreate
*/
void OckRpcServerDestroy(OckRpcServer server);
* @brief Send a reply.
*
* The @b ctx is passed to the user along with the request message through
* @ref OckRpcMsgHandler .
*
* The message id of this reply must be the same as the request message ID.
*
* If @b done is not nullptr, this routine behaves as an asynchronous routine. When
* this routine return OCK_RPC_OK, it only means that the operation is triggered,
* and the real result will be reported to the user through @b done. The @b done
* may be executed in the routine, please pay attention to this. Before the done
* execution, the memory in the @b reply cannot be released.
*
* If @b done is nullptr, the return value means the the real result.
*
* @param ctx Context passed to the user through @ref OckRpcMsgHandler .
* @param msgId Message ID.
* @param reply Reply message.
* @param done Notify the result to user.
* @return OCK_RPC_OK for success and others for failure. If @b done is not nullptr,
* OCK_RPC_OK means it's still inprogress.
*/
OckRpcStatus OckRpcServerReply(OckRpcServerContext ctx, uint16_t msgId,
OckRpcMessage* reply, OckRpcCallDone* done);
* @brief Cleanup the server context.
*
* Once cleaned up, the context can no longer be used, and the message data pointer
* passed to the user together with it can no longer be used too.
*
* @param ctx Context passed to user through @ref OckRpcMsgHandler.
*/
void OckRpcServerCleanupCtx(OckRpcServerContext ctx);
* @brief Connect to server with config.
*
* Connect to a specified address and return a handler that can be used to rpc call.
*
* @param ip Server IP.
* @param port Server port.
* @param client Client handle that connected to the server.
* @param cfg The create configs.
* @return OCK_RPC_OK for success and others for failure.
*/
OckRpcStatus OckRpcClientConnectWithCfg(const char* ip, uint16_t port, OckRpcClient* client,
OckRpcCreateConfig* cfg);
* @brief Disconnect.
*
* After this routine, the client handle can not be used again.
*
* @param client Client handle returned by @ref OckRpcClientConnect
*/
void OckRpcClientDisconnect(OckRpcClient client);
* @brief Send request and receive response(optional).
*
* If @b response is nullptr, it just sends the request and returns.
*
* If @b response is not nullptr, it will receives a response. If user does not
* know the real length of the response, user can set @b response->data to nullptr,
* so RPC will allocate enough memroy to hold the response, and store the memory
* address to @b response->data. User are required to use free() to release this
* memory. There will be additional overhead.
*
* If @b done is not nullptr, this routine behaves as an asynchronous routine,
* and all memory like @b response can not be released until the @b done is invoked.
* @b done will be called to notify the real result. The @b done may be executed
* in the routine, please pay attention to this
*
* If @b done is nullptr, the return value means the the real result.
*
* @param client Client handle.
* @param msgId Message ID.
* @param request Request.
* @param response Response, can be nullptr.
* @param done Notify the result to user.
* @return OckRpcStatus OCK_RPC_OK for success and others for failure. If @b done is not nullptr,
* OCK_RPC_OK means it's still inprogress.
*/
OckRpcStatus OckRpcClientCall(OckRpcClient client, uint16_t msgId,
OckRpcMessage* request, OckRpcMessage* response,
OckRpcCallDone* done);
* @brief Same with OckRpcClientCall()
*/
OckRpcStatus OckRpcClientCallWithParam(OckRpcClientCallParams *params);
* @brief Set timeout
*
* After setting timeout by this routine, if the @ref OckRpcClientCall is not
* completed within the specified time, a failure is returned.
*
* 1. timeout = 0: return immediately
* 2. timeout < 0: never timeout, usually set to -1
* 3. timeout > 0: Millisecond precision timeout.
* Default timeout is -1.
*
* @param client Client.
* @param timeout Milliseconds.
*/
void OckRpcClientSetTimeout(OckRpcClient client, int64_t timeout);
* @brief Disable the HMAC check when use SSL transfer data.
* @note This is global configure, it will affect all servers and clients
*/
void OckRpcDisableSecureHmac(void);
#ifdef __cplusplus
}
#endif
#endif