botsense  3.2.0
RoadNarrows Client-Server Proxied Services Framework
bsProxyClient.c File Reference

BotSense bsProxy client routines. More...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "rnr/rnrconfig.h"
#include "rnr/log.h"
#include "rnr/new.h"
#include "rnr/sock.h"
#include "rnr/netmsgs.h"
#include "botsense/BotSense.h"
#include "botsense/bsProxyMsgs.h"
#include "bsProxy.h"

Go to the source code of this file.

Macros

#define CLIENT_HND(pClient)   ServerClientSd2Hnd(SocketAttrGetSd(pClient->m_pClientSock))
 Convert pointer to client to client handle. More...
 

Functions

static void ClientLockBusy ()
 Lock client's global busy mutual exclusion.
 
static void ClientUnlockBusy ()
 Unlock client's global busy mutual exclusion.
 
static bool_t ClientBusyTryLock ()
 Try to lock client's global busy mutual exclusion. More...
 
static void ClientBroadcastNotBusy ()
 Broadcast that a client has been freed or deleted. More...
 
static void ClientWaitNotBusy ()
 Wait on a client to become free.
 
static void fdset_nowarn (int fd, fd_set *pset)
 FD_SET() wrapper with no annoying warnings. More...
 
static ssize_t ClientRead (BsProxyClientCtl_T *pClient, byte_t buf[], size_t uCount)
 Read count bytes from socket. More...
 
static ssize_t ClientWrite (BsProxyClientCtl_T *pClient, byte_t buf[], size_t uCount)
 Write count bytes to socket. More...
 
static ssize_t ClientResync (BsProxyClientCtl_T *pClient, byte_t bufHdr[])
 Resync to client message stream. More...
 
static void ClientFlushInput (BsProxyClientCtl_T *pClient, size_t uCount)
 Flush receive stream. More...
 
void ClientOneTimeInit ()
 The BotSense bsProxy server one-time client control initialization.
 
BsProxyClientCtl_TClientAcquire (BsProxyClientHnd_T hndClient)
 Acquire client, locking it from other threads. More...
 
void ClientRelease (BsProxyClientHnd_T hndClient)
 Release the locked client. More...
 
BsProxyClientCtl_TClientNew (Socket_T *pSockClient)
 Create new client control structure. More...
 
void ClientDelete (BsProxyClientCtl_T *pClient)
 Delete a client with the server. More...
 
void ClientSetState (BsProxyClientCtl_T *pClient, BsProxyClientState_T eNewState)
 Set client's state. More...
 
static int ClientRecvHdr (BsProxyClientCtl_T *pClient, BsProxyMsgHdr_T *pMsgHdr)
 Receive client request header. More...
 
static int ClientRecvBody (BsProxyClientCtl_T *pClient, byte_t buf[], size_t uBodyLen)
 Receive client request message body. More...
 
int ClientRecvReq (BsProxyClientHnd_T hndClient, BsProxyMsgHdr_T *pMsgHdr, byte_t **addrBuf)
 Receive a request message from client. More...
 
int ClientSendOkRsp (BsProxyClientHnd_T hndClient, BsTid_T uTid)
 Send an ok response to the client. More...
 
int ClientSendErrorRsp (BsProxyClientHnd_T hndClient, BsTid_T uTid, int nECode, const char *sErrFmt,...)
 Send an error response to the client. More...
 
int ClientSendVErrorRsp (BsProxyClientHnd_T hndClient, BsTid_T uTid, int nECode, const char *sErrFmt, va_list ap)
 Send va_list error response to the client. More...
 
int ClientSendServerRsp (BsProxyClientHnd_T hndClient, BsTid_T uTid, BsProxyMsgId_T uMsgId, void *pMsgRsp)
 Send a server-terminated response message to client. More...
 
int ClientSendRsp (BsProxyClientHnd_T hndClient, BsVConnHnd_T hndVConn, BsTid_T uTid, BsMsgId_T uMsgId, byte_t bufRsp[], size_t uRspSize)
 Send module-specific response to the client. More...
 

Variables

static pthread_mutex_t BsClientBusyMutex
 busy mutex
 
static pthread_cond_t BsClientBusyCond
 busy condition
 

Detailed Description

BotSense bsProxy client routines.

LastChangedDate
2010-08-20 11:36:38 -0600 (Fri, 20 Aug 2010)
Rev
568
Author
Robin Knight (robin.nosp@m..kni.nosp@m.ght@r.nosp@m.oadn.nosp@m.arrow.nosp@m.s.co.nosp@m.m)

Definition in file bsProxyClient.c.

Macro Definition Documentation

#define CLIENT_HND (   pClient)    ServerClientSd2Hnd(SocketAttrGetSd(pClient->m_pClientSock))

Convert pointer to client to client handle.

Parameters
pClient

Definition at line 81 of file bsProxyClient.c.

Referenced by ClientRecvBody(), and ClientRecvHdr().

Function Documentation

BsProxyClientCtl_T* ClientAcquire ( BsProxyClientHnd_T  hndClient)

Acquire client, locking it from other threads.

The calling thread is blocked until the client is availble or has been deleted.

Parameters
hndClientClient handle.
Returns
On success, returns pointer to locked client control block. On failure, NULL is returned.

Definition at line 546 of file bsProxyClient.c.

References ClientLockBusy(), ClientUnlockBusy(), ClientWaitNotBusy(), BsProxyClientCtl_T::m_bBusy, and ServerGetClient().

Referenced by BsProxyClientUnregister(), ClientRecvReq(), ClientSendRsp(), ClientSetTraceState(), ReqDevClose(), and ReqDevOpen().

547 {
548  BsProxyClientCtl_T *pClient;
549 
550  ClientLockBusy();
551 
552  while( ((pClient = ServerGetClient(hndClient)) != NULL) && pClient->m_bBusy )
553  {
555  }
556 
557  if( pClient )
558  {
559  pClient->m_bBusy = true;
560  }
561 
563 
564  return pClient;
565 }
static void ClientUnlockBusy()
Unlock client&#39;s global busy mutual exclusion.
bool_t m_bBusy
client is [not] busy
Definition: bsProxy.h:194
INLINE_IN_H BsProxyClientCtl_T * ServerGetClient(BsProxyClientHnd_T hndClient)
Get the <b><i>BotSense</i></b> server client.
Definition: bsProxy.h:551
static void ClientLockBusy()
Lock client&#39;s global busy mutual exclusion.
Definition: bsProxyClient.c:91
static void ClientWaitNotBusy()
Wait on a client to become free.
static void ClientBroadcastNotBusy ( )
inlinestatic

Broadcast that a client has been freed or deleted.

A broadcast will unblock all threads currently blocked on the busy condition variable. Only those threads waiting on the client whose condition has changed will run. If multiple threads are waiting on the same client, then only one is schedule to run.

Definition at line 136 of file bsProxyClient.c.

References BsClientBusyCond.

Referenced by ClientRelease().

137 {
138  int rc;
139 
140  if( (rc = pthread_cond_broadcast(&BsClientBusyCond)) != 0 )
141  {
142  errno = rc;
143  LOGSYSERROR("pthread_cond_broadcast()");
144  }
145 }
static pthread_cond_t BsClientBusyCond
busy condition
Definition: bsProxyClient.c:74
static bool_t ClientBusyTryLock ( )
inlinestatic

Try to lock client's global busy mutual exclusion.

Returns
Returns true if lock is acquired. Otherwise returns false if mutex already locked.

Definition at line 123 of file bsProxyClient.c.

References BsClientBusyMutex.

124 {
125  return pthread_mutex_trylock(&BsClientBusyMutex) == 0? true: false;
126 }
static pthread_mutex_t BsClientBusyMutex
busy mutex
Definition: bsProxyClient.c:73
void ClientDelete ( BsProxyClientCtl_T pClient)

Delete a client with the server.

Parameters
pClient

Definition at line 621 of file bsProxyClient.c.

References BsProxyClientCtl_T::m_pClientSock, and BsProxyClientCtl_T::m_sClientName.

Referenced by BsProxyClientUnregister(), and ClientSetTraceState().

622 {
623  if( pClient != NULL )
624  {
625  SocketClose(pClient->m_pClientSock);
626  SocketDelete(pClient->m_pClientSock);
627  delete((char *)pClient->m_sClientName);
628  delete(pClient);
629  }
630 }
Socket_T * m_pClientSock
client opened TCP socket
Definition: bsProxy.h:196
const char * m_sClientName
client&#39;s (remote) name
Definition: bsProxy.h:195
static void ClientFlushInput ( BsProxyClientCtl_T pClient,
size_t  uCount 
)
static

Flush receive stream.

Parameters
pClient

Definition at line 501 of file bsProxyClient.c.

References ClientRead().

Referenced by ClientRecvHdr().

502 {
503  byte_t buf[256];
504  ssize_t k = 0;
505  size_t n;
506 
507  do
508  {
509  uCount -= (size_t)k;
510  n = sizeof(buf) < uCount? sizeof(buf): uCount;
511  } while( (n > 0) && ((k = ClientRead(pClient, buf, n)) > 0) );
512 }
static ssize_t ClientRead(BsProxyClientCtl_T *pClient, byte_t buf[], size_t uCount)
Read count bytes from socket.
BsProxyClientCtl_T* ClientNew ( Socket_T *  pSockClient)

Create new client control structure.

Parameters
pSockClientAccecpted client socket.
Returns
Returns a newly allocated and intialized client control block.

Definition at line 602 of file bsProxyClient.c.

References BsProxyClientStateNominal, BsProxyClientCtl_T::m_bServerTrace, BsProxyClientCtl_T::m_eClientState, BsProxyClientCtl_T::m_pClientSock, BsProxyClientCtl_T::m_sClientName, and BsProxyClientCtl_T::m_uRefCnt.

Referenced by BsProxyClientRegister(), and ClientSetTraceState().

603 {
604  BsProxyClientCtl_T *pClient;
605 
606  pClient = NEW(BsProxyClientCtl_T);
607  pClient->m_sClientName = new_strdup(SocketAttrGetRemoteName(pSockClient));
608  pClient->m_pClientSock = pSockClient;
610  pClient->m_uRefCnt = 0;
611  pClient->m_bServerTrace = false;
612 
613  return pClient;
614 }
BsProxyClientState_T m_eClientState
client state
Definition: bsProxy.h:197
Socket_T * m_pClientSock
client opened TCP socket
Definition: bsProxy.h:196
bool_t m_bServerTrace
do [not] trace server messages
Definition: bsProxy.h:199
uint_t m_uRefCnt
vconn ref count for this client
Definition: bsProxy.h:198
normal operation
Definition: bsProxy.h:184
const char * m_sClientName
client&#39;s (remote) name
Definition: bsProxy.h:195
static ssize_t ClientRead ( BsProxyClientCtl_T pClient,
byte_t  buf[],
size_t  uCount 
)
static

Read count bytes from socket.

Parameters
pClient

Definition at line 188 of file bsProxyClient.c.

References BS_ECODE_BAD_RECV, BS_ECODE_SERVER_BAD_CLIENT, BSPROXY_LOG_SYSERROR, BSPROXY_TUNE_T_RECV, BsProxyClientStateZombie, ClientThisHasName(), fdset_nowarn(), ServerClientSd2Hnd(), timer_elapsed(), and timer_mark().

Referenced by ClientFlushInput(), ClientRecvBody(), ClientRecvHdr(), and ClientResync().

191 {
192  uint_t usec = BSPROXY_TUNE_T_RECV;
193  struct timeval tstart;
194  uint_t tdelta;
195  struct timeval timeout;
196  fd_set rset;
197  int sd;
198  int nFd;
199  ssize_t n;
200  ssize_t nBytes = 0;
201 
202  LOGDIAG4CALL(_TSTR(ClientThisHasName(pClient)), _TPTR(buf), _TUINT(uCount));
203 
204  // client is disconnected or in an unrecoverable state
205  if( pClient->m_eClientState == BsProxyClientStateZombie )
206  {
208  }
209 
210  // socket descriptor
211  sd = SocketAttrGetSd(pClient->m_pClientSock);
212 
213  //
214  // Read the data until either 1) count bytes are read, 2) a time out occurs,
215  // or 3) an error occurs.
216  //
217  while( nBytes < uCount )
218  {
219  FD_ZERO(&rset);
220  fdset_nowarn(sd, &rset);
221 
222  // mark now
223  timer_mark(&tstart);
224 
225  // (re)load timeout (gets munged after each select())
226  timeout.tv_sec = (time_t)(usec / 1000000);
227  timeout.tv_usec = (time_t)(usec % 1000000);
228 
229  // wait to bytes to be available to be read
230  nFd = select(sd+1, &rset, NULL, NULL, &timeout);
231 
232  // system error occurred on select - interpret
233  if( nFd < 0 )
234  {
235  switch(errno)
236  {
237  case EAGAIN: // non-blocking timeout
238  case EINTR: // read was interrupted
239  break;
240  default: // non-recoverable error
241  BSPROXY_LOG_SYSERROR(ServerClientSd2Hnd(sd), "select(%d,...)", sd);
242  return -BS_ECODE_BAD_RECV;
243  }
244  }
245 
246  // select() timeout occurred
247  else if( nFd == 0 )
248  {
249  LOGDIAG4("select() on read timed out.");
250  break;
251  }
252 
253  // read the available data from the socket
254  n = read(sd, buf+nBytes, uCount-(size_t)nBytes);
255 
256  // system error occurred on read - interpret
257  if( n < 0 )
258  {
259  switch(errno)
260  {
261  case EAGAIN: // non-blocking timeout
262  case EINTR: // read was interrupted
263  n = 0;
264  break;
265  default: // non-recoverable error
266  BSPROXY_LOG_SYSERROR(ServerClientSd2Hnd(sd), "select(%d,...)", sd);
267  return -BS_ECODE_BAD_RECV;
268  }
269  }
270 
271  // got some data
272  nBytes += n;
273 
274  // all of the requested bytes have been read
275  if( nBytes == uCount )
276  {
277  break;
278  }
279 
280  // determine time left for the non-blocking read timeout
281  if( nBytes < uCount )
282  {
283  tdelta = timer_elapsed(&tstart);
284  if( tdelta >= usec )
285  {
286  LOGDIAG4("%s() timed out.", LOGFUNCNAME);
287  break;
288  }
289  else
290  {
291  usec -= tdelta;
292  }
293  }
294  }
295 
296  LOGDIAG4("%s(): %zd bytes read.", LOGFUNCNAME, nBytes);
297 
298  return nBytes;
299 }
static uint_t timer_elapsed(struct timeval *pTvMark)
Calculate the elapsed time between the given time mark and this call.
Definition: bsLibClient.c:358
BsProxyClientState_T m_eClientState
client state
Definition: bsProxy.h:197
static void fdset_nowarn(int fd, fd_set *pset)
FD_SET() wrapper with no annoying warnings.
#define BS_ECODE_BAD_RECV
bad receive
Definition: BotSense.h:69
Socket_T * m_pClientSock
client opened TCP socket
Definition: bsProxy.h:196
#define BSPROXY_LOG_SYSERROR(hndClient, efmt,...)
Log Proxy Server System Error.
Definition: bsProxy.h:314
INLINE_IN_H BsProxyClientHnd_T ServerClientSd2Hnd(int sd)
Convert the <b><i>BotSense</i></b> server client socket descriptor to client handle.
Definition: bsProxy.h:537
disconnected or fatal, not deleted
Definition: bsProxy.h:186
#define BS_ECODE_SERVER_BAD_CLIENT
server detected bad client
Definition: BotSense.h:91
static void timer_mark(struct timeval *pTvMark)
Mark the current time. Resolution is microseconds.
Definition: bsLibClient.c:340
#define BSPROXY_TUNE_T_RECV
1.0s receive time out
Definition: bsProxy.h:94
INLINE_IN_H const char * ClientThisHasName(BsProxyClientCtl_T *pClient)
Get this <b><i>BotSense</i></b> client official name.
Definition: bsProxy.h:574
static int ClientRecvBody ( BsProxyClientCtl_T pClient,
byte_t  buf[],
size_t  uBodyLen 
)
static

Receive client request message body.

Sanity checks are performed on the message.

Parameters
pClient

Definition at line 798 of file bsProxyClient.c.

References BS_ECODE_BAD_RECV, BS_ECODE_MSG_FRAG, BSPROXY_LOG_ERROR, BsProxyClientStateReSync, CLIENT_HND, ClientRead(), and ClientSetState().

Referenced by ClientRecvReq().

801 {
802  int nBytes; // bytes read
803 
804  // read failed
805  if( (nBytes = (int)ClientRead(pClient, buf, uBodyLen)) < 0 )
806  {
808  "Failed to receive client message body.");
809  return -BS_ECODE_BAD_RECV;
810  }
811 
812  // read a message fragment
813  else if( nBytes < (ssize_t)uBodyLen )
814  {
816  "Received length=%zd, expected length=%zu.", nBytes, uBodyLen);
818  nBytes = 0;
819  }
820 
821  return nBytes;
822 }
#define BS_ECODE_BAD_RECV
bad receive
Definition: BotSense.h:69
void ClientSetState(BsProxyClientCtl_T *pClient, BsProxyClientState_T eNewState)
Set client&#39;s state.
#define BSPROXY_LOG_ERROR(hndClient, ecode, efmt,...)
Log Proxy Server Error.
Definition: bsProxy.h:288
#define CLIENT_HND(pClient)
Convert pointer to client to client handle.
Definition: bsProxyClient.c:81
static ssize_t ClientRead(BsProxyClientCtl_T *pClient, byte_t buf[], size_t uCount)
Read count bytes from socket.
#define BS_ECODE_MSG_FRAG
message fragment
Definition: BotSense.h:73
resyncing server with client
Definition: bsProxy.h:185
static int ClientRecvHdr ( BsProxyClientCtl_T pClient,
BsProxyMsgHdr_T pMsgHdr 
)
static

Receive client request header.

Sanity checks are performed on the header.

Parameters
pClient

< normal operation

< resyncing server with client

< disconnected/bad state, but not deleted

Definition at line 702 of file bsProxyClient.c.

References BS_ECODE_BAD_RECV, BS_ECODE_MSG_BAD_HDR, BS_ECODE_MSG_FRAG, BS_ECODE_MSG_TOO_BIG, BS_ECODE_SERVER_BAD_CLIENT, BSPROXY_LOG_ERROR, BSPROXY_MSG_BODY_MAX, BSPROXY_MSG_HDR_LEN, BSPROXY_MSG_MAGIC, BsProxyClientStateNominal, BsProxyClientStateReSync, BsProxyClientStateZombie, CLIENT_HND, ClientFlushInput(), ClientRead(), ClientResync(), ClientSetState(), BsProxyClientCtl_T::m_eClientState, BsProxyMsgHdr_T::m_hdrBodyLen, and BsProxyMsgHdr_T::m_hdrMagic.

Referenced by ClientRecvReq().

703 {
704  byte_t bufHdr[BSPROXY_MSG_HDR_LEN]; // header buffer
705  int nBytes; // bytes read
706  size_t uBodyLen; // length of message body
707 
708  //
709  // Read the message header. The method depends on the client's state.
710  // Nominal Normal operation
711  // Resync Need to find the start of a header in stream, then read header
712  // Zombie Client is disconnecting, simply return error.
713  //
714  switch( pClient->m_eClientState )
715  {
716  case BsProxyClientStateNominal: ///< normal operation
717  nBytes = (int)ClientRead(pClient, bufHdr, BSPROXY_MSG_HDR_LEN);
718  break;
719  case BsProxyClientStateReSync: ///< resyncing server with client
720  nBytes = (int)ClientResync(pClient, bufHdr);
721  break;
722  case BsProxyClientStateZombie: ///< disconnected/bad state, but not deleted
723  default:
725  }
726 
727  // receive error
728  if( nBytes < 0 )
729  {
730  return -BS_ECODE_BAD_RECV;
731  }
732 
733  // nothing to receive
734  else if( nBytes == 0 )
735  {
736  return 0;
737  }
738 
739  // received header fragment, enter resync state
740  else if( nBytes < BSPROXY_MSG_HDR_LEN )
741  {
743  "Received %d bytes, expected %d byte header.",
744  nBytes, BSPROXY_MSG_HDR_LEN);
746  return 0;
747  }
748 
749  // unpack message header
750  else if( bsUnpackMsgHdr(bufHdr, (size_t)nBytes, pMsgHdr) < 0 )
751  {
753  "Received bad message header.");
755  return 0;
756  }
757 
758  // validate magic
759  else if( pMsgHdr->m_hdrMagic != BSPROXY_MSG_MAGIC )
760  {
762  "Received bad magic 0x%04x in message header.",
763  pMsgHdr->m_hdrMagic);
765  return 0;
766  }
767 
768  //
769  // The message body is too long.
770  //
771  else if( pMsgHdr->m_hdrBodyLen > BSPROXY_MSG_BODY_MAX )
772  {
773  uBodyLen = (size_t)pMsgHdr->m_hdrBodyLen;
775  "Received body length=%zu, flushing.", uBodyLen);
776  ClientFlushInput(pClient, uBodyLen);
777  return 0;
778  }
779 
780  else
781  {
782  return nBytes;
783  }
784 }
BsProxyClientState_T m_eClientState
client state
Definition: bsProxy.h:197
#define BS_ECODE_BAD_RECV
bad receive
Definition: BotSense.h:69
static ssize_t ClientResync(BsProxyClientCtl_T *pClient, byte_t bufHdr[])
Resync to client message stream.
static void ClientFlushInput(BsProxyClientCtl_T *pClient, size_t uCount)
Flush receive stream.
void ClientSetState(BsProxyClientCtl_T *pClient, BsProxyClientState_T eNewState)
Set client&#39;s state.
ushort_t m_hdrBodyLen
message body length
Definition: BotSense.h:284
disconnected or fatal, not deleted
Definition: bsProxy.h:186
#define BS_ECODE_MSG_TOO_BIG
message too big
Definition: BotSense.h:74
#define BS_ECODE_MSG_BAD_HDR
bad message header
Definition: BotSense.h:72
#define BSPROXY_MSG_MAGIC
message magic pattern
Definition: BotSense.h:261
#define BSPROXY_MSG_HDR_LEN
message header length (bytes)
Definition: BotSense.h:258
ushort_t m_hdrMagic
"unique" magic pattern
Definition: BotSense.h:280
#define BSPROXY_LOG_ERROR(hndClient, ecode, efmt,...)
Log Proxy Server Error.
Definition: bsProxy.h:288
#define CLIENT_HND(pClient)
Convert pointer to client to client handle.
Definition: bsProxyClient.c:81
static ssize_t ClientRead(BsProxyClientCtl_T *pClient, byte_t buf[], size_t uCount)
Read count bytes from socket.
normal operation
Definition: bsProxy.h:184
#define BSPROXY_MSG_BODY_MAX
maximum msg body length (sans header)
Definition: BotSense.h:123
#define BS_ECODE_SERVER_BAD_CLIENT
server detected bad client
Definition: BotSense.h:91
#define BS_ECODE_MSG_FRAG
message fragment
Definition: BotSense.h:73
resyncing server with client
Definition: bsProxy.h:185
int ClientRecvReq ( BsProxyClientHnd_T  hndClient,
BsProxyMsgHdr_T pMsgHdr,
byte_t **  addrBuf 
)

Receive a request message from client.

Parameters
hndClient

Definition at line 836 of file bsProxyClient.c.

References BS_ECODE_SERVER_BAD_CLIENT, BSPROXY_LOG_REQ, BsProxyClientStateNominal, ClientAcquire(), ClientRecvBody(), ClientRecvHdr(), ClientRelease(), ClientSetState(), ClientThisHasName(), BsProxyClientCtl_T::m_eClientState, BsProxyMsgHdr_T::m_hdrBodyLen, and ServerHasName().

Referenced by BsProxyServer(), and ClientSetTraceState().

839 {
840  BsProxyClientCtl_T *pClient; // BotSense client
841  size_t uBodyLen; // expected message body length
842  byte_t *pBuf = NULL; // allocated request packed message body
843  int nBytesHdr; // read message header bytes/return code
844  int nBytesBody; // read message body bytes/return code
845  int nMsgLen; // total message length/return code
846 
847  *addrBuf = NULL;
848 
849  // lock client
850  if( (pClient = ClientAcquire(hndClient)) == NULL )
851  {
853  }
854 
855  // receive message header
856  if( (nBytesHdr = ClientRecvHdr(pClient, pMsgHdr)) <= 0 )
857  {
858  nMsgLen = nBytesHdr; // return code
859  }
860 
861  // received a good header, now receive any message body
862  else
863  {
864  // (reenter) nominal state
865  if( pClient->m_eClientState != BsProxyClientStateNominal )
866  {
868  }
869 
870  BSPROXY_LOG_REQ(hndClient, pMsgHdr);
871 
872  // specified message body length
873  uBodyLen = (size_t)pMsgHdr->m_hdrBodyLen;
874 
875  //
876  // Get the message body.
877  //
878  if( uBodyLen > 0 )
879  {
880  // allocate buffer
881  pBuf = (byte_t *)new(uBodyLen);
882 
883  // receive
884  if( (nBytesBody = ClientRecvBody(pClient, pBuf, uBodyLen)) <= 0 )
885  {
886  delete(pBuf);
887  pBuf = NULL;
888  nMsgLen = nBytesBody; // return code
889  }
890 
891  // success
892  else
893  {
894  nMsgLen = nBytesHdr + nBytesBody;
895  }
896  }
897 
898  //
899  // No message body
900  //
901  else
902  {
903  pBuf = NULL;
904  nMsgLen = nBytesHdr;
905  }
906  }
907 
908  // set allocated buffer
909  *addrBuf = pBuf;
910 
911  if( nMsgLen > 0 )
912  {
913  LOGDIAG3("%s: %s: received message length=%d",
914  ServerHasName(), ClientThisHasName(pClient), nMsgLen);
915  }
916 
917  // unlock client
918  ClientRelease(hndClient);
919 
920  return nMsgLen;
921 }
BsProxyClientState_T m_eClientState
client state
Definition: bsProxy.h:197
static int ClientRecvHdr(BsProxyClientCtl_T *pClient, BsProxyMsgHdr_T *pMsgHdr)
Receive client request header.
#define BSPROXY_LOG_REQ(hndClient, pMsgHdr)
Log client request.
Definition: bsProxy.h:384
BsProxyClientCtl_T * ClientAcquire(BsProxyClientHnd_T hndClient)
Acquire client, locking it from other threads.
INLINE_IN_H const char * ServerHasName()
Get the <b><i>BotSense</i></b> server&#39;s official name.
Definition: bsProxy.h:485
void ClientSetState(BsProxyClientCtl_T *pClient, BsProxyClientState_T eNewState)
Set client&#39;s state.
void ClientRelease(BsProxyClientHnd_T hndClient)
Release the locked client.
ushort_t m_hdrBodyLen
message body length
Definition: BotSense.h:284
normal operation
Definition: bsProxy.h:184
#define BS_ECODE_SERVER_BAD_CLIENT
server detected bad client
Definition: BotSense.h:91
static int ClientRecvBody(BsProxyClientCtl_T *pClient, byte_t buf[], size_t uBodyLen)
Receive client request message body.
INLINE_IN_H const char * ClientThisHasName(BsProxyClientCtl_T *pClient)
Get this <b><i>BotSense</i></b> client official name.
Definition: bsProxy.h:574
void ClientRelease ( BsProxyClientHnd_T  hndClient)

Release the locked client.

A broadcast is sent to all blocking threads on the freed event.

Parameters
hndClientClient handle.

Definition at line 574 of file bsProxyClient.c.

References ClientBroadcastNotBusy(), ClientLockBusy(), ClientUnlockBusy(), BsProxyClientCtl_T::m_bBusy, and ServerGetClient().

Referenced by ClientRecvReq(), ClientSendRsp(), ClientSetTraceState(), ReqDevClose(), and ReqDevOpen().

575 {
576  BsProxyClientCtl_T *pClient;
577 
578  ClientLockBusy();
579 
580  if( (pClient = ServerGetClient(hndClient)) != NULL )
581  {
582  pClient->m_bBusy = false;
583  }
584 
586 
588 }
static void ClientUnlockBusy()
Unlock client&#39;s global busy mutual exclusion.
bool_t m_bBusy
client is [not] busy
Definition: bsProxy.h:194
INLINE_IN_H BsProxyClientCtl_T * ServerGetClient(BsProxyClientHnd_T hndClient)
Get the <b><i>BotSense</i></b> server client.
Definition: bsProxy.h:551
static void ClientLockBusy()
Lock client&#39;s global busy mutual exclusion.
Definition: bsProxyClient.c:91
static void ClientBroadcastNotBusy()
Broadcast that a client has been freed or deleted.
static ssize_t ClientResync ( BsProxyClientCtl_T pClient,
byte_t  bufHdr[] 
)
static

Resync to client message stream.

If a client receieve stream becomes unsynchronized, the message headers are aliased to some offset into the stream. To resync, bsProxy searches the stream for the magic bytes in the message header. Once found, the reset of the header is read.

Parameters
pClient

Definition at line 436 of file bsProxyClient.c.

References BSPROXY_MSG_HDR_LEN, BSPROXY_MSG_MAGIC, and ClientRead().

Referenced by ClientRecvHdr().

437 {
438  enum ReSyncState_T {GetMagicHi, GetMagicLo, GetRoH};
439  byte_t byMagicHi = (byte_t)((BSPROXY_MSG_MAGIC >> 8) & 0xff);
440  byte_t byMagicLo = (byte_t)(BSPROXY_MSG_MAGIC & 0xff);
441  size_t uCount = BSPROXY_MSG_HDR_LEN;
442  size_t n = 0;
443  enum ReSyncState_T eCurState = GetMagicHi;
444 
445  byte_t buf[BSPROXY_MSG_HDR_LEN];
446  ssize_t nBytes;
447  int i;
448 
449  //
450  // Search stream for message header.
451  //
452  while( (nBytes = ClientRead(pClient, buf, uCount)) > 0 )
453  {
454  for(i=0; i<nBytes; ++i)
455  {
456  switch( eCurState )
457  {
458  case GetMagicHi: // get some high magic
459  if( buf[i] == byMagicHi )
460  {
461  bufHdr[n++] = buf[i];
462  eCurState = GetMagicLo;
463  }
464  break;
465  case GetMagicLo: // now get some low magic
466  if( buf[i] == byMagicLo )
467  {
468  bufHdr[n++] = buf[i];
469  eCurState = GetRoH;
470  }
471  else // false magic
472  {
473  n = 0;
474  eCurState = GetMagicHi;
475  }
476  break;
477  case GetRoH: // get rest of header
478  bufHdr[n++] = buf[i];
479  break;
480  }
481  }
482 
483  uCount = BSPROXY_MSG_HDR_LEN - n;
484 
485  if( uCount == 0 )
486  {
487  nBytes = BSPROXY_MSG_HDR_LEN;
488  break;
489  }
490  }
491 
492  return nBytes;
493 }
#define BSPROXY_MSG_MAGIC
message magic pattern
Definition: BotSense.h:261
#define BSPROXY_MSG_HDR_LEN
message header length (bytes)
Definition: BotSense.h:258
static ssize_t ClientRead(BsProxyClientCtl_T *pClient, byte_t buf[], size_t uCount)
Read count bytes from socket.
int ClientSendErrorRsp ( BsProxyClientHnd_T  hndClient,
BsTid_T  uTid,
int  nECode,
const char *  sErrFmt,
  ... 
)

Send an error response to the client.

Parameters
hndClient

Definition at line 960 of file bsProxyClient.c.

References ClientSendVErrorRsp().

Referenced by ClientSetTraceState().

965 {
966  va_list ap;
967  int rc;
968 
969  va_start(ap, sErrFmt);
970  rc = ClientSendVErrorRsp(hndClient, uTid, nECode, sErrFmt,ap);
971  va_end(ap);
972  return rc;
973 }
int ClientSendVErrorRsp(BsProxyClientHnd_T hndClient, BsTid_T uTid, int nECode, const char *sErrFmt, va_list ap)
Send va_list error response to the client.
int ClientSendOkRsp ( BsProxyClientHnd_T  hndClient,
BsTid_T  uTid 
)

Send an ok response to the client.

Parameters
hndClient

Definition at line 936 of file bsProxyClient.c.

References BSPROXY_MSG_HDR_LEN, BSPROXY_VCONN_SERVER, BsProxyMsgIdRspOk, and ClientSendRsp().

Referenced by ClientSetTraceState(), ModCbSendOkRsp(), ReqDevClose(), ReqMsgTrace(), and ReqSetLogging().

937 {
938  byte_t bufRsp[BSPROXY_MSG_HDR_LEN];
939 
940  //
941  // Send the ok message.
942  // Note: Even though this is a server defined message, there is no message
943  // body, so use the lower level send function directly.
944  //
945  return ClientSendRsp(hndClient, BSPROXY_VCONN_SERVER, uTid,
946  BsProxyMsgIdRspOk, bufRsp, (size_t)0);
947 }
int ClientSendRsp(BsProxyClientHnd_T hndClient, BsVConnHnd_T hndVConn, BsTid_T uTid, BsMsgId_T uMsgId, byte_t bufRsp[], size_t uRspSize)
Send module-specific response to the client.
#define BSPROXY_VCONN_SERVER
handle for server-terminated msgs
Definition: BotSense.h:140
#define BSPROXY_MSG_HDR_LEN
message header length (bytes)
Definition: BotSense.h:258
int ClientSendRsp ( BsProxyClientHnd_T  hndClient,
BsVConnHnd_T  hndVConn,
BsTid_T  uTid,
BsMsgId_T  uMsgId,
byte_t  bufRsp[],
size_t  uRspSize 
)

Send module-specific response to the client.

Parameters
hndClient

Definition at line 1084 of file bsProxyClient.c.

References BS_ECODE_BAD_SEND, BS_ECODE_INTERNAL, BS_ECODE_SERVER_BAD_CLIENT, BSPROXY_LOG_ERROR, BSPROXY_LOG_RSP, BSPROXY_LOG_SYSERROR, BSPROXY_MSG_HDR_LEN, BSPROXY_MSG_MAGIC, ClientAcquire(), ClientRelease(), ClientWrite(), BsProxyMsgHdr_T::m_hdrBodyLen, BsProxyMsgHdr_T::m_hdrMagic, BsProxyMsgHdr_T::m_hdrMsgId, BsProxyMsgHdr_T::m_hdrTid, and BsProxyMsgHdr_T::m_hdrVConn.

Referenced by ClientSendOkRsp(), ClientSendServerRsp(), ClientSetTraceState(), and ModCbSendRsp().

1090 {
1091  BsProxyClientCtl_T *pClient;
1092  BsProxyMsgHdr_T msgHdr;
1093  size_t nBytes;
1094  int n;
1095 
1096  // message header
1097  msgHdr.m_hdrMagic = (ushort_t)BSPROXY_MSG_MAGIC;
1098  msgHdr.m_hdrTid = (byte_t)uTid;
1099  msgHdr.m_hdrVConn = (byte_t)hndVConn;
1100  msgHdr.m_hdrMsgId = (ushort_t)uMsgId;
1101  msgHdr.m_hdrBodyLen = (ushort_t)uRspSize;
1102 
1103  n = bsPackMsgHdr(&msgHdr, bufRsp, BSPROXY_MSG_HDR_LEN);
1104 
1105  if( n < 0 )
1106  {
1107  BSPROXY_LOG_ERROR(hndClient, n,
1108  "Failed to pack message header for MsgId=%u.", uMsgId);
1109  return -BS_ECODE_INTERNAL;
1110  }
1111 
1112  nBytes = (size_t)n + uRspSize;
1113 
1114  if( (pClient = ClientAcquire(hndClient)) == NULL )
1115  {
1117  "Failed to acquire Client=%d.", hndClient);
1119  }
1120 
1121  // send message to client
1122  n = (int)ClientWrite(pClient, bufRsp, nBytes);
1123 
1124  ClientRelease(hndClient);
1125 
1126  if( n < 0 )
1127  {
1128  BSPROXY_LOG_SYSERROR(hndClient,
1129  "Failed to send message, MsgId=%u", uMsgId);
1130  return -BS_ECODE_BAD_SEND;
1131  }
1132 
1133  // success
1134  else
1135  {
1136  BSPROXY_LOG_RSP(hndClient, &msgHdr);
1137  return n;
1138  }
1139 }
static ssize_t ClientWrite(BsProxyClientCtl_T *pClient, byte_t buf[], size_t uCount)
Write count bytes to socket.
#define BSPROXY_LOG_SYSERROR(hndClient, efmt,...)
Log Proxy Server System Error.
Definition: bsProxy.h:314
#define BS_ECODE_BAD_SEND
bad send
Definition: BotSense.h:70
BsProxyClientCtl_T * ClientAcquire(BsProxyClientHnd_T hndClient)
Acquire client, locking it from other threads.
#define BSPROXY_LOG_RSP(hndClient, pMsgHdr)
Log client request.
Definition: bsProxy.h:404
void ClientRelease(BsProxyClientHnd_T hndClient)
Release the locked client.
ushort_t m_hdrBodyLen
message body length
Definition: BotSense.h:284
ushort_t m_hdrMsgId
message id (vConnection unique)
Definition: BotSense.h:283
#define BSPROXY_MSG_MAGIC
message magic pattern
Definition: BotSense.h:261
#define BSPROXY_MSG_HDR_LEN
message header length (bytes)
Definition: BotSense.h:258
ushort_t m_hdrMagic
"unique" magic pattern
Definition: BotSense.h:280
#define BSPROXY_LOG_ERROR(hndClient, ecode, efmt,...)
Log Proxy Server Error.
Definition: bsProxy.h:288
BotSense Proxy Message Header Structure.
Definition: BotSense.h:278
#define BS_ECODE_SERVER_BAD_CLIENT
server detected bad client
Definition: BotSense.h:91
#define BS_ECODE_INTERNAL
internal error (bug)
Definition: BotSense.h:93
byte_t m_hdrTid
transaction id
Definition: BotSense.h:281
byte_t m_hdrVConn
virtual connection handle (server unique)
Definition: BotSense.h:282
int ClientSendServerRsp ( BsProxyClientHnd_T  hndClient,
BsTid_T  uTid,
BsProxyMsgId_T  uMsgId,
void *  pMsgRsp 
)

Send a server-terminated response message to client.

The response message header must contain the information except for the body length which will be automatically calculated.

Parameters
hndClient

Definition at line 1025 of file bsProxyClient.c.

References BS_ECODE_INTERNAL, BSPROXY_BUF_BODY, BSPROXY_LOG_ERROR, BSPROXY_LOG_NMERROR, BSPROXY_MSG_MAX_LEN, BSPROXY_VCONN_SERVER, BsProxyLookupMsgDef(), BsProxyPackMsg(), ClientGetTraceState(), and ClientSendRsp().

Referenced by ClientSendVErrorRsp(), ClientSetTraceState(), ReqDevOpen(), ReqGetVConnInfo(), ReqGetVConnList(), ReqGetVersion(), and ReqLoopback().

1029 {
1030  const NMMsgDef_T *pMsgDef;
1031  byte_t bufRsp[BSPROXY_MSG_MAX_LEN];
1032  int n;
1033 
1034  // find the bsProxy server message definition
1035  pMsgDef = BsProxyLookupMsgDef(uMsgId);
1036 
1037  if( pMsgDef == NULL )
1038  {
1040  "Cannot find message definition for MsgId=%u.", uMsgId);
1041  return -BS_ECODE_INTERNAL;
1042  }
1043 
1044  //
1045  // Pack response message body
1046  //
1047  if( pMsgRsp != NULL )
1048  {
1049  n = BsProxyPackMsg(uMsgId, pMsgRsp, BSPROXY_BUF_BODY(bufRsp),
1050  ClientGetTraceState(hndClient));
1051 
1052  if( n < 0 )
1053  {
1054  BSPROXY_LOG_NMERROR(hndClient, n,
1055  "Failed to pack message body for MsgId=%u.", uMsgId);
1056  return -BS_ECODE_INTERNAL;
1057  }
1058  }
1059 
1060  //
1061  // No response message body
1062  //
1063  else
1064  {
1065  n = 0;
1066  }
1067 
1068  return ClientSendRsp(hndClient, BSPROXY_VCONN_SERVER, uTid, uMsgId,
1069  bufRsp, (size_t)n);
1070 }
int ClientSendRsp(BsProxyClientHnd_T hndClient, BsVConnHnd_T hndVConn, BsTid_T uTid, BsMsgId_T uMsgId, byte_t bufRsp[], size_t uRspSize)
Send module-specific response to the client.
const NMMsgDef_T * BsProxyLookupMsgDef(BsProxyMsgId_T eMsgId)
Look up the message definition associated with the message id.
Definition: bsProxyMsgs.c:874
#define BSPROXY_VCONN_SERVER
handle for server-terminated msgs
Definition: BotSense.h:140
INLINE_IN_H bool_t ClientGetTraceState(BsProxyClientHnd_T hndClient)
Get the <b><i>BotSense</i></b> client&#39;s server-terminated message trace state.
Definition: bsProxy.h:602
#define BSPROXY_LOG_ERROR(hndClient, ecode, efmt,...)
Log Proxy Server Error.
Definition: bsProxy.h:288
#define BSPROXY_LOG_NMERROR(hndClient, nmecode, efmt,...)
Log Proxy Server NetMsgs (Un)Packing Error.
Definition: bsProxy.h:302
#define BS_ECODE_INTERNAL
internal error (bug)
Definition: BotSense.h:93
#define BSPROXY_BUF_BODY(buf)
Convenience macro to produce a buffer (offset, size) 2-tuple.
Definition: BotSense.h:272
#define BSPROXY_MSG_MAX_LEN
total message maximum length
Definition: BotSense.h:259
int BsProxyPackMsg(BsProxyMsgId_T eMsgId, void *pStruct, byte_t buf[], size_t bufSize, bool_t bTrace)
Pack a ITV message in big-endian byte order.
Definition: bsProxyMsgs.c:924
int ClientSendVErrorRsp ( BsProxyClientHnd_T  hndClient,
BsTid_T  uTid,
int  nECode,
const char *  sErrFmt,
va_list  ap 
)

Send va_list error response to the client.

Parameters
hndClient

Definition at line 986 of file bsProxyClient.c.

References BSPROXY_RSPERR_EMSG_LEN, BsProxyMsgIdRspErr, ClientSendServerRsp(), BsProxyRspErr_T::m_ecode, and BsProxyRspErr_T::m_emsg.

Referenced by ClientSendErrorRsp(), ClientSetTraceState(), and ModCbSendErrorRsp().

991 {
992  BsProxyRspErr_T msgRsp;
993 
994  // Fill in formatted error string as the response message body.
995  vsnprintf(msgRsp.m_emsg, BSPROXY_RSPERR_EMSG_LEN+1, sErrFmt, ap);
996  msgRsp.m_emsg[BSPROXY_RSPERR_EMSG_LEN] = 0;
997 
998  // set error code
999  if( nECode < 0 )
1000  {
1001  nECode = -nECode;
1002  }
1003  msgRsp.m_ecode = (byte_t)nECode;
1004 
1005  // send error message
1006  ClientSendServerRsp(hndClient, uTid, BsProxyMsgIdRspErr, &msgRsp);
1007 
1008  return -nECode;
1009 }
char m_emsg[(NMFVAL_LEN_MAX_STRING)+1]
emsg
Definition: bsProxyMsgs.h:75
int ClientSendServerRsp(BsProxyClientHnd_T hndClient, BsTid_T uTid, BsProxyMsgId_T uMsgId, void *pMsgRsp)
Send a server-terminated response message to client.
byte_t m_ecode
ecode
Definition: bsProxyMsgs.h:74
#define BSPROXY_RSPERR_EMSG_LEN
Definition: bsProxyMsgs.h:67
void ClientSetState ( BsProxyClientCtl_T pClient,
BsProxyClientState_T  eNewState 
)

Set client's state.

Parameters
pClient

< disconnected but not deleted

< normal operation

< resyncing server with client

Definition at line 643 of file bsProxyClient.c.

References BsProxyClientStateNominal, BsProxyClientStateReSync, BsProxyClientStateZombie, ClientThisHasName(), BsProxyClientCtl_T::m_eClientState, BsProxyClientCtl_T::m_sClientName, and ServerHasName().

Referenced by BsProxyClientUnregister(), ClientRecvBody(), ClientRecvHdr(), ClientRecvReq(), and ClientSetTraceState().

644 {
645  static const char *sZombie = "(zombie)";
646 
647  const char *sState;
648  char *sName;
649  size_t n;
650 
651  if( pClient == NULL )
652  {
653  return;
654  }
655 
656  else if( pClient->m_eClientState == eNewState )
657  {
658  return;
659  }
660 
661  switch( eNewState )
662  {
663  case BsProxyClientStateZombie: ///< disconnected but not deleted
664  sState = "disconnected";
665  n = strlen(pClient->m_sClientName) + strlen(sZombie) + 2;
666  sName = NEWSTR(n);
667  sprintf(sName, "%s %s", pClient->m_sClientName, sZombie);
668  delete((char *)pClient->m_sClientName);
669  pClient->m_sClientName = sName;
670  break;
671  case BsProxyClientStateNominal: ///< normal operation
672  sState = "nominal";
673  break;
674  case BsProxyClientStateReSync: ///< resyncing server with client
675  sState = "resyncing";
676  break;
677  default:
678  return;
679  }
680 
681  pClient->m_eClientState = eNewState;
682 
683  LOGDIAG2("%s: %s: %s.", ServerHasName(), ClientThisHasName(pClient), sState);
684 }
BsProxyClientState_T m_eClientState
client state
Definition: bsProxy.h:197
INLINE_IN_H const char * ServerHasName()
Get the <b><i>BotSense</i></b> server&#39;s official name.
Definition: bsProxy.h:485
disconnected or fatal, not deleted
Definition: bsProxy.h:186
normal operation
Definition: bsProxy.h:184
const char * m_sClientName
client&#39;s (remote) name
Definition: bsProxy.h:195
resyncing server with client
Definition: bsProxy.h:185
INLINE_IN_H const char * ClientThisHasName(BsProxyClientCtl_T *pClient)
Get this <b><i>BotSense</i></b> client official name.
Definition: bsProxy.h:574
static ssize_t ClientWrite ( BsProxyClientCtl_T pClient,
byte_t  buf[],
size_t  uCount 
)
static

Write count bytes to socket.

Parameters
pClient

Definition at line 311 of file bsProxyClient.c.

References BS_ECODE_BAD_SEND, BS_ECODE_SERVER_BAD_CLIENT, BSPROXY_LOG_SYSERROR, BSPROXY_TUNE_T_SEND, BsProxyClientStateZombie, ClientThisHasName(), fdset_nowarn(), BsProxyClientCtl_T::m_eClientState, BsProxyClientCtl_T::m_pClientSock, ServerClientSd2Hnd(), timer_elapsed(), and timer_mark().

Referenced by ClientSendRsp().

314 {
315  uint_t usec = BSPROXY_TUNE_T_SEND;
316  struct timeval tstart;
317  uint_t tdelta;
318  struct timeval timeout;
319  fd_set wset;
320  int sd;
321  int nFd;
322  ssize_t n;
323  ssize_t nBytes = 0;
324 
325  LOGDIAG4CALL(_TSTR(ClientThisHasName(pClient)), _TPTR(buf), _TUINT(uCount));
326 
327  // client is disconnected or in an unrecoverable state
328  if( pClient->m_eClientState == BsProxyClientStateZombie )
329  {
331  }
332 
333  // socket descriptor
334  sd = SocketAttrGetSd(pClient->m_pClientSock);
335 
336  //
337  // Write the data until either 1) count bytes are written, 2) a time out
338  // occurs, or 3) an error occurs.
339  //
340  while( nBytes < uCount )
341  {
342  FD_ZERO(&wset);
343  fdset_nowarn(sd, &wset);
344 
345  // mark now
346  timer_mark(&tstart);
347 
348  // (re)load timeout (gets munged after each select())
349  timeout.tv_sec = (time_t)(usec / 1000000);
350  timeout.tv_usec = (time_t)(usec % 1000000);
351 
352  nFd = select(sd+1, NULL, &wset, NULL, &timeout);
353 
354  // system error occurred on select - interpret
355  if( nFd < 0 )
356  {
357  switch(errno)
358  {
359  case EAGAIN: // non-blocking timeout
360  case EINTR: // write was interrupted
361  break;
362  default: // non-recoverable error
363  BSPROXY_LOG_SYSERROR(ServerClientSd2Hnd(sd), "select(%d,...)", sd);
364  return -BS_ECODE_BAD_SEND;
365  }
366  }
367 
368  // select() timeout occurred
369  else if( nFd == 0 )
370  {
371  LOGDIAG4("select() on write timed out.");
372  break;
373  }
374 
375  // socket is available for writing
376  n = write(sd, buf+nBytes, uCount-(size_t)nBytes);
377 
378  // system error occurred on write - interpret
379  if( n < 0 )
380  {
381  switch(errno)
382  {
383  case EAGAIN: // non-blocking timeout
384  case EINTR: // write was interrupted
385  n = 0;
386  break;
387  default: // non-recoverable error
388  BSPROXY_LOG_SYSERROR(ServerClientSd2Hnd(sd), "select(%d,...)", sd);
389  return -BS_ECODE_BAD_SEND;
390  }
391  }
392 
393  // wrote some data
394  nBytes += n;
395 
396  // all of the requested bytes have been written
397  if( nBytes == uCount )
398  {
399  break;
400  }
401 
402  // determine time left for non-blocking write timeout
403  if( nBytes < uCount )
404  {
405  tdelta = timer_elapsed(&tstart);
406  if( tdelta >= usec )
407  {
408  LOGDIAG4("%s() timed out.", LOGFUNCNAME);
409  break;
410  }
411  else
412  {
413  usec -= tdelta;
414  }
415  }
416  }
417 
418  LOGDIAG4("%s(): %zd bytes written.", LOGFUNCNAME, nBytes);
419 
420  return nBytes;
421 }
static uint_t timer_elapsed(struct timeval *pTvMark)
Calculate the elapsed time between the given time mark and this call.
Definition: bsLibClient.c:358
BsProxyClientState_T m_eClientState
client state
Definition: bsProxy.h:197
static void fdset_nowarn(int fd, fd_set *pset)
FD_SET() wrapper with no annoying warnings.
Socket_T * m_pClientSock
client opened TCP socket
Definition: bsProxy.h:196
#define BSPROXY_LOG_SYSERROR(hndClient, efmt,...)
Log Proxy Server System Error.
Definition: bsProxy.h:314
#define BS_ECODE_BAD_SEND
bad send
Definition: BotSense.h:70
INLINE_IN_H BsProxyClientHnd_T ServerClientSd2Hnd(int sd)
Convert the <b><i>BotSense</i></b> server client socket descriptor to client handle.
Definition: bsProxy.h:537
disconnected or fatal, not deleted
Definition: bsProxy.h:186
#define BS_ECODE_SERVER_BAD_CLIENT
server detected bad client
Definition: BotSense.h:91
static void timer_mark(struct timeval *pTvMark)
Mark the current time. Resolution is microseconds.
Definition: bsLibClient.c:340
#define BSPROXY_TUNE_T_SEND
0.5s send time out
Definition: bsProxy.h:95
INLINE_IN_H const char * ClientThisHasName(BsProxyClientCtl_T *pClient)
Get this <b><i>BotSense</i></b> client official name.
Definition: bsProxy.h:574
static void fdset_nowarn ( int  fd,
fd_set *  pset 
)
inlinestatic

FD_SET() wrapper with no annoying warnings.

Parameters
fdFile descriptor to add to set.
psetPointer to fd set.

Definition at line 172 of file bsProxyClient.c.

Referenced by ClientRead(), and ClientWrite().

173 {
174  FD_SET(fd, pset);
175 }