--- libaitrpc/src/cli.c 2012/05/16 16:36:10 1.9.2.7 +++ libaitrpc/src/cli.c 2012/05/17 22:57:42 1.9.2.15 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: cli.c,v 1.9.2.7 2012/05/16 16:36:10 misho Exp $ +* $Id: cli.c,v 1.9.2.15 2012/05/17 22:57:42 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -102,7 +102,8 @@ rpc_cli_openBLOBClient(rpc_cli_t * __restrict rpccli, close(cli->cli_sock); free(cli); return NULL; - } + } else + fcntl(cli->cli_sock, F_SETFL, fcntl(cli->cli_sock, F_GETFL) | O_NONBLOCK); return cli; } @@ -135,7 +136,7 @@ rpc_cli_closeBLOBClient(rpc_cli_t ** __restrict cli) * * @ProgID = ProgramID for RPC session request * @ProcID = ProcessID for RPC session request - * @netBuf = Network buffer length, if =0 == BUFSIZ (also meaning max RPC packet) + * @netBuf = Network buffer length (min:512 bytes), if =0 == BUFSIZ (also meaning max RPC packet) * @csHost = Host name or IP address for bind server * @Port = Port for bind server, if Port == 0 default port is selected * return: NULL == error or !=NULL connection to RPC server established @@ -150,8 +151,10 @@ rpc_cli_openClient(u_int ProgID, u_char ProcID, int ne return NULL; if (!Port) Port = RPC_DEFPORT; - if (!netBuf) + if (netBuf < RPC_MIN_BUFSIZ) netBuf = BUFSIZ; + else + netBuf = io_align(netBuf, 1); /* align netBuf length */ #ifdef HAVE_SRANDOMDEV srandomdev(); @@ -199,7 +202,8 @@ rpc_cli_openClient(u_int ProgID, u_char ProcID, int ne free(cli->cli_parent); free(cli); return NULL; - } + } else + fcntl(cli->cli_sock, F_SETFL, fcntl(cli->cli_sock, F_GETFL) | O_NONBLOCK); return cli; } @@ -235,8 +239,8 @@ rpc_cli_closeClient(rpc_cli_t ** __restrict cli) * @cli = RPC Client session * @noreply = We not want RPC reply * @tag = Function tag for execution - * @in_vars = IN RPC call array of rpc values - * @out_vars = OUT returned array of rpc values, must be free after use with rpc_cli_freeVals() + * @in_vars = IN RPC call array of rpc values, may be NULL + * @out_vars = OUT returned array of rpc values, if !=NULL must be free after use with io_freeVars() * return: -1 error or != -1 ok result */ int @@ -262,6 +266,7 @@ rpc_cli_execCall(rpc_cli_t *cli, int noreply, u_short rpc_addPktSession(&rpc->call_session, cli->cli_parent); rpc->call_argc = htons(io_arraySize(in_vars)); rpc->call_tag = htons(tag); + rpc->call_seq = htons(random() % USHRT_MAX); /* set reply */ rpc->call_req.flags = noreply ? RPC_NOREPLY : RPC_REPLY; @@ -283,6 +288,21 @@ rpc_cli_execCall(rpc_cli_t *cli, int noreply, u_short rpc->call_crc ^= rpc->call_crc; rpc->call_crc = htons(crcFletcher16((u_short*) buf, wlen / 2)); + pfd.fd = cli->cli_sock; + pfd.events = POLLOUT; + do { + if ((ret = poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000)) < 1 || + pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) { + if (ret) { + if (errno == EAGAIN) + continue; + else + LOGERR; + } else + rpc_SetErr(ETIMEDOUT, "Timeout, can't send to RPC server"); + return -1; + } + } while (0); if ((ret = send(cli->cli_sock, buf, wlen, MSG_NOSIGNAL)) == -1) { LOGERR; return -1; @@ -296,17 +316,20 @@ rpc_cli_execCall(rpc_cli_t *cli, int noreply, u_short return 0; /* reply from RPC server */ - pfd.fd = cli->cli_sock; pfd.events = POLLIN | POLLPRI; - if ((ret = poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000)) == -1 || - pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) { - if (ret) - LOGERR; - else - rpc_SetErr(ETIMEDOUT, "Timeout, no answer from RPC server"); - - return -1; - } + do { + if ((ret = poll(&pfd, 1, DEF_RPC_TIMEOUT * 1000)) < 1 || + pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) { + if (ret) { + if (errno == EAGAIN) + continue; + else + LOGERR; + } else + rpc_SetErr(ETIMEDOUT, "Timeout, no answer from RPC server"); + return -1; + } + } while (0); memset(buf, 0, AIT_LEN(&cli->cli_buf)); if ((ret = recv(cli->cli_sock, buf, AIT_LEN(&cli->cli_buf), 0)) < 1) { if (ret) @@ -348,14 +371,39 @@ rpc_cli_execCall(rpc_cli_t *cli, int noreply, u_short } /* RPC is OK! Go de-marshaling variables ... */ - if (ntohs(rpc->call_argc)) { + if (out_vars && ntohs(rpc->call_argc)) { *out_vars = io_buffer2vars(buf + wlen, AIT_LEN(&cli->cli_buf) - wlen, ntohs(rpc->call_argc), 0); if (!*out_vars) { + rpc_SetErr(io_GetErrno(), "%s", io_GetError()); return -1; } } ret = ntohl(rpc->call_rep.ret); + return ret; +} + +/* + * rpc_cli_ping() - Ping RPC server + * + * @cli = connected client + * return: -1 error or !=-1 ping seq id + */ +inline int +rpc_cli_ping(rpc_cli_t *cli) +{ + int ret = 0; + array_t *arr = NULL; + + if (!cli) + return -1; + + if (rpc_cli_execCall(cli, RPC_REPLY, CALL_SRVPING, NULL, &arr)) + return -1; + else + ret = AIT_GET_U16(io_getVars(arr, 0)); + io_freeVars(&arr); + return ret; }