--- libaitrpc/src/cli.c 2012/03/15 01:55:33 1.7 +++ libaitrpc/src/cli.c 2012/03/29 01:23:59 1.7.2.3 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: cli.c,v 1.7 2012/03/15 01:55:33 misho Exp $ +* $Id: cli.c,v 1.7.2.3 2012/03/29 01:23:59 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -163,7 +163,7 @@ rpc_cli_openClient(u_int ProgID, u_int ProcID, int net int n; if (!csHost || (family != AF_INET && family != AF_INET6 && family != AF_LOCAL)) { - rpc_SetErr(EINVAL, "Error:: Invalid parameters can`t connect to RPC server ...\n"); + rpc_SetErr(EINVAL, "Invalid parameters can`t connect to RPC server ..."); return NULL; } if (!Port) @@ -175,7 +175,7 @@ rpc_cli_openClient(u_int ProgID, u_int ProcID, int net if (csHost && family != AF_LOCAL) { host = gethostbyname2(csHost, family); if (!host) { - rpc_SetErr(h_errno, "Error:: %s\n", hstrerror(h_errno)); + rpc_SetErr(h_errno, "%s", hstrerror(h_errno)); return NULL; } } @@ -200,7 +200,7 @@ rpc_cli_openClient(u_int ProgID, u_int ProcID, int net strlcpy(sa.sun.sun_path, csHost, sizeof sa.sun.sun_path); break; default: - rpc_SetErr(EINVAL, "Error:: Invalid parameters can`t connect to RPC server ...\n"); + rpc_SetErr(EINVAL, "Invalid parameters can`t connect to RPC server ..."); return NULL; } @@ -288,6 +288,7 @@ rpc_cli_closeClient(rpc_cli_t * __restrict cli) * rpc_cli_execCall() - Execute RPC call * * @cli = RPC Client session + * @noreply = We not want RPC reply * @csModule = Module name, if NULL self binary * @csFunc = Function name for execute * @in_vars = IN RPC call array of rpc values @@ -295,7 +296,7 @@ rpc_cli_closeClient(rpc_cli_t * __restrict cli) * return: -1 error or != -1 ok result */ int -rpc_cli_execCall(rpc_cli_t *cli, const char *csModule, const char *csFunc, +rpc_cli_execCall(rpc_cli_t *cli, int noreply, const char *csModule, const char *csFunc, array_t * __restrict in_vars, array_t ** __restrict out_vars) { fd_set fds; @@ -304,7 +305,7 @@ rpc_cli_execCall(rpc_cli_t *cli, const char *csModule, struct tagRPCCall *rpc; int ret = 0, wlen = sizeof(struct tagRPCCall); struct timeval tv = { DEF_RPC_TIMEOUT, 0 }; - uint16_t tag; + uint16_t tag, crc; uint32_t hash; if (!cli || !csFunc) { @@ -338,6 +339,9 @@ rpc_cli_execCall(rpc_cli_t *cli, const char *csModule, rpc->call_tag = tag; rpc->call_hash = hash; + /* set reply */ + rpc->call_req.flags = noreply ? RPC_NOREPLY : RPC_REPLY; + if (io_arraySize(in_vars)) { /* marshaling variables */ ret = io_vars2buffer(buf + wlen, cli->cli_netbuf - wlen, in_vars); @@ -349,9 +353,11 @@ rpc_cli_execCall(rpc_cli_t *cli, const char *csModule, wlen += ret; } + rpc->call_len = htons(wlen); + /* calculate CRC */ rpc->call_crc ^= rpc->call_crc; - rpc->call_crc = htons(crcFletcher16((u_short*) buf, io_align(wlen, 1) / 2)); + rpc->call_crc = htons(crcFletcher16((u_short*) buf, wlen / 2)); if ((ret = send(cli->cli_sock, buf, wlen, 0)) == -1) { LOGERR; @@ -364,6 +370,12 @@ rpc_cli_execCall(rpc_cli_t *cli, const char *csModule, return -1; } + if (noreply) { + /* we not want reply */ + free(buf); + return 0; + } + /* reply from RPC server */ FD_ZERO(&fds); FD_SET(cli->cli_sock, &fds); @@ -371,7 +383,7 @@ rpc_cli_execCall(rpc_cli_t *cli, const char *csModule, if (ret) LOGERR; else - rpc_SetErr(ETIMEDOUT, "Error:: timeout, no return from RPC server?\n"); + rpc_SetErr(ETIMEDOUT, "Timeout, no return from RPC server?"); free(buf); return -1; @@ -380,40 +392,50 @@ rpc_cli_execCall(rpc_cli_t *cli, const char *csModule, if ((ret = recv(cli->cli_sock, buf, cli->cli_netbuf, 0)) == -1) { LOGERR; free(buf); - return -3; + return -1; } if (!ret) { /* receive EOF! */ free(buf); return 0; } if (ret < sizeof(struct tagRPCCall)) { - rpc_SetErr(ERPCMISMATCH, "Error:: too short RPC packet ...\n"); + rpc_SetErr(ERPCMISMATCH, "Too short RPC packet ..."); free(buf); - return -4; + return -1; } + + /* calculate CRC */ + crc = ntohs(rpc->call_crc); + rpc->call_crc ^= rpc->call_crc; + if (crc != crcFletcher16((u_short*) buf, ret / 2)) { + rpc_SetErr(ERPCMISMATCH, "Bad CRC RPC packet"); + free(buf); + return -1; + } + /* check RPC packet session info */ if (rpc_chkPktSession(&rpc->call_session, cli->cli_parent)) { - rpc_SetErr(ERPCMISMATCH, "Error:: get invalid RPC session ...\n"); + rpc_SetErr(ERPCMISMATCH, "Get invalid RPC session ..."); free(buf); - return -5; + return -1; } else wlen = sizeof(struct tagRPCCall); if (rpc->call_tag != tag || rpc->call_hash != hash) { - rpc_SetErr(ERPCMISMATCH, "Error:: get wrong RPC reply ...\n"); + rpc_SetErr(ERPCMISMATCH, "Get wrong RPC reply ..."); free(buf); - return -5; + return -1; } if (ntohl(rpc->call_rep.ret) < 0 && ntohl(rpc->call_rep.eno)) { - rpc_SetErr(ntohl(rpc->call_rep.eno), "Error::Server side: retcode=%d #%d %s\n", + rpc_SetErr(ntohl(rpc->call_rep.eno), "Server side: retcode=%d #%d %s", ntohl(rpc->call_rep.ret), ntohl(rpc->call_rep.eno), strerror(ntohl(rpc->call_rep.eno))); free(buf); - return -6; + return -1; } if (ntohs(rpc->call_argc) * sizeof(ait_val_t) > cli->cli_netbuf - wlen) { - rpc_SetErr(EMSGSIZE, "Error:: reply RPC packet is too long ...\n"); + rpc_SetErr(EMSGSIZE, "Reply RPC packet is too long ..."); free(buf); - return -7; + return -1; } /* RPC is OK! Go de-marshaling variables ... */