54 #include "rnr/rnrconfig.h" 58 #include "rnr/netmsgs.h" 81 #define CLIENT_HND(pClient) \ 82 ServerClientSd2Hnd(SocketAttrGetSd(pClient->m_pClientSock)) 98 LOGSYSERROR(
"pthread_mutex_lock()");
112 LOGSYSERROR(
"pthread_mutex_unlock()");
143 LOGSYSERROR(
"pthread_cond_broadcast()");
157 LOGSYSERROR(
"pthread_cond_wait()");
166 PRAGMA_IGNORED(sign-conversion)
176 PRAGMA_WARNING(sign-conversion)
193 struct timeval tstart;
195 struct timeval timeout;
211 sd = SocketAttrGetSd(pClient->m_pClientSock);
217 while( nBytes < uCount )
226 timeout.tv_sec = (time_t)(usec / 1000000);
227 timeout.tv_usec = (time_t)(usec % 1000000);
230 nFd = select(sd+1, &rset, NULL, NULL, &timeout);
249 LOGDIAG4(
"select() on read timed out.");
254 n = read(sd, buf+nBytes, uCount-(
size_t)nBytes);
275 if( nBytes == uCount )
281 if( nBytes < uCount )
286 LOGDIAG4(
"%s() timed out.", LOGFUNCNAME);
296 LOGDIAG4(
"%s(): %zd bytes read.", LOGFUNCNAME, nBytes);
316 struct timeval tstart;
318 struct timeval timeout;
340 while( nBytes < uCount )
349 timeout.tv_sec = (time_t)(usec / 1000000);
350 timeout.tv_usec = (time_t)(usec % 1000000);
352 nFd = select(sd+1, NULL, &wset, NULL, &timeout);
371 LOGDIAG4(
"select() on write timed out.");
376 n = write(sd, buf+nBytes, uCount-(
size_t)nBytes);
397 if( nBytes == uCount )
403 if( nBytes < uCount )
408 LOGDIAG4(
"%s() timed out.", LOGFUNCNAME);
418 LOGDIAG4(
"%s(): %zd bytes written.", LOGFUNCNAME, nBytes);
438 enum ReSyncState_T {GetMagicHi, GetMagicLo, GetRoH};
443 enum ReSyncState_T eCurState = GetMagicHi;
452 while( (nBytes =
ClientRead(pClient, buf, uCount)) > 0 )
454 for(i=0; i<nBytes; ++i)
459 if( buf[i] == byMagicHi )
461 bufHdr[n++] = buf[i];
462 eCurState = GetMagicLo;
466 if( buf[i] == byMagicLo )
468 bufHdr[n++] = buf[i];
474 eCurState = GetMagicHi;
478 bufHdr[n++] = buf[i];
510 n =
sizeof(buf) < uCount?
sizeof(buf): uCount;
511 }
while( (n > 0) && ((k =
ClientRead(pClient, buf, n)) > 0) );
607 pClient->
m_sClientName = new_strdup(SocketAttrGetRemoteName(pSockClient));
623 if( pClient != NULL )
645 static const char *sZombie =
"(zombie)";
651 if( pClient == NULL )
664 sState =
"disconnected";
675 sState =
"resyncing";
734 else if( nBytes == 0 )
743 "Received %d bytes, expected %d byte header.",
750 else if( bsUnpackMsgHdr(bufHdr, (
size_t)nBytes, pMsgHdr) < 0 )
753 "Received bad message header.");
762 "Received bad magic 0x%04x in message header.",
775 "Received body length=%zu, flushing.", uBodyLen);
805 if( (nBytes = (
int)
ClientRead(pClient, buf, uBodyLen)) < 0 )
808 "Failed to receive client message body.");
813 else if( nBytes < (ssize_t)uBodyLen )
816 "Received length=%zd, expected length=%zu.", nBytes, uBodyLen);
881 pBuf = (byte_t *)
new(uBodyLen);
888 nMsgLen = nBytesBody;
894 nMsgLen = nBytesHdr + nBytesBody;
913 LOGDIAG3(
"%s: %s: received message length=%d",
969 va_start(ap, sErrFmt);
1003 msgRsp.
m_ecode = (byte_t)nECode;
1030 const NMMsgDef_T *pMsgDef;
1037 if( pMsgDef == NULL )
1040 "Cannot find message definition for MsgId=%u.", uMsgId);
1047 if( pMsgRsp != NULL )
1055 "Failed to pack message body for MsgId=%u.", uMsgId);
1108 "Failed to pack message header for MsgId=%u.", uMsgId);
1112 nBytes = (size_t)n + uRspSize;
1117 "Failed to acquire Client=%d.", hndClient);
1129 "Failed to send message, MsgId=%u", uMsgId);
static void ClientUnlockBusy()
Unlock client's global busy mutual exclusion.
uint_t BsMsgId_T
client message id type [0-64k].
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.
static uint_t timer_elapsed(struct timeval *pTvMark)
Calculate the elapsed time between the given time mark and this call.
BsProxyClientState_T m_eClientState
client state
<b><i>BotSense</i></b> bsProxy IP server declarations.
static void fdset_nowarn(int fd, fd_set *pset)
FD_SET() wrapper with no annoying warnings.
const NMMsgDef_T * BsProxyLookupMsgDef(BsProxyMsgId_T eMsgId)
Look up the message definition associated with the message id.
BotSense client application - bsProxy server-terminated core messages.
#define BS_ECODE_BAD_RECV
bad receive
static int ClientRecvHdr(BsProxyClientCtl_T *pClient, BsProxyMsgHdr_T *pMsgHdr)
Receive client request header.
int ClientRecvReq(BsProxyClientHnd_T hndClient, BsProxyMsgHdr_T *pMsgHdr, byte_t **addrBuf)
Receive a request message from client.
BsProxyClientCtl_T * ClientNew(Socket_T *pSockClient)
Create new client control structure.
uint_t BsTid_T
client transaction id type [0-255].
static ssize_t ClientWrite(BsProxyClientCtl_T *pClient, byte_t buf[], size_t uCount)
Write count bytes to socket.
#define BSPROXY_LOG_REQ(hndClient, pMsgHdr)
Log client request.
Socket_T * m_pClientSock
client opened TCP socket
#define BSPROXY_LOG_SYSERROR(hndClient, efmt,...)
Log Proxy Server System Error.
static pthread_mutex_t BsClientBusyMutex
busy mutex
#define BSPROXY_VCONN_SERVER
handle for server-terminated msgs
#define BS_ECODE_BAD_SEND
bad send
BsProxyClientCtl_T * ClientAcquire(BsProxyClientHnd_T hndClient)
Acquire client, locking it from other threads.
bool_t m_bBusy
client is [not] busy
INLINE_IN_H const char * ServerHasName()
Get the <b><i>BotSense</i></b> server's official name.
int ClientSendErrorRsp(BsProxyClientHnd_T hndClient, BsTid_T uTid, int nECode, const char *sErrFmt,...)
Send an error response to the client.
static ssize_t ClientResync(BsProxyClientCtl_T *pClient, byte_t bufHdr[])
Resync to client message stream.
bool_t m_bServerTrace
do [not] trace server messages
static void ClientFlushInput(BsProxyClientCtl_T *pClient, size_t uCount)
Flush receive stream.
void ClientDelete(BsProxyClientCtl_T *pClient)
Delete a client with the server.
void ClientSetState(BsProxyClientCtl_T *pClient, BsProxyClientState_T eNewState)
Set client's state.
int BsProxyClientHnd_T
bsProxy server client handle
INLINE_IN_H BsProxyClientHnd_T ServerClientSd2Hnd(int sd)
Convert the <b><i>BotSense</i></b> server client socket descriptor to client handle.
#define BSPROXY_LOG_RSP(hndClient, pMsgHdr)
Log client request.
char m_emsg[(NMFVAL_LEN_MAX_STRING)+1]
emsg
void ClientRelease(BsProxyClientHnd_T hndClient)
Release the locked client.
static pthread_cond_t BsClientBusyCond
busy condition
INLINE_IN_H bool_t ClientGetTraceState(BsProxyClientHnd_T hndClient)
Get the <b><i>BotSense</i></b> client's server-terminated message trace state.
ushort_t m_hdrBodyLen
message body length
ushort_t m_hdrMsgId
message id (vConnection unique)
disconnected or fatal, not deleted
#define BS_ECODE_MSG_TOO_BIG
message too big
INLINE_IN_H BsProxyClientCtl_T * ServerGetClient(BsProxyClientHnd_T hndClient)
Get the <b><i>BotSense</i></b> server client.
int ClientSendServerRsp(BsProxyClientHnd_T hndClient, BsTid_T uTid, BsProxyMsgId_T uMsgId, void *pMsgRsp)
Send a server-terminated response message to client.
void ClientOneTimeInit()
The <b><i>BotSense</i></b> bsProxy server one-time client control initialization.
#define BS_ECODE_MSG_BAD_HDR
bad message header
uint_t m_uRefCnt
vconn ref count for this client
#define BSPROXY_MSG_MAGIC
message magic pattern
#define BSPROXY_MSG_HDR_LEN
message header length (bytes)
ushort_t m_hdrMagic
"unique" magic pattern
#define BSPROXY_LOG_ERROR(hndClient, ecode, efmt,...)
Log Proxy Server Error.
#define CLIENT_HND(pClient)
Convert pointer to client to client handle.
static ssize_t ClientRead(BsProxyClientCtl_T *pClient, byte_t buf[], size_t uCount)
Read count bytes from socket.
BotSense Proxy Message Header Structure.
#define BSPROXY_LOG_NMERROR(hndClient, nmecode, efmt,...)
Log Proxy Server NetMsgs (Un)Packing Error.
int ClientSendOkRsp(BsProxyClientHnd_T hndClient, BsTid_T uTid)
Send an ok response to the client.
#define BSPROXY_MSG_BODY_MAX
maximum msg body length (sans header)
#define BS_ECODE_SERVER_BAD_CLIENT
server detected bad client
#define BS_ECODE_MSG_FRAG
message fragment
#define BS_ECODE_INTERNAL
internal error (bug)
#define BSPROXY_BUF_BODY(buf)
Convenience macro to produce a buffer (offset, size) 2-tuple.
byte_t m_hdrTid
transaction id
static void ClientLockBusy()
Lock client's global busy mutual exclusion.
static void ClientBroadcastNotBusy()
Broadcast that a client has been freed or deleted.
const char * m_sClientName
client's (remote) name
#define BSPROXY_MSG_MAX_LEN
total message maximum length
static void timer_mark(struct timeval *pTvMark)
Mark the current time. Resolution is microseconds.
#define BSPROXY_TUNE_T_SEND
0.5s send time out
#define BSPROXY_TUNE_T_RECV
1.0s receive time out
resyncing server with client
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.
byte_t m_hdrVConn
virtual connection handle (server unique)
static bool_t ClientBusyTryLock()
Try to lock client's global busy mutual exclusion.
static void ClientWaitNotBusy()
Wait on a client to become free.
static int ClientRecvBody(BsProxyClientCtl_T *pClient, byte_t buf[], size_t uBodyLen)
Receive client request message body.
<b><i>BotSense</i></b> package top-level, unifying header declarations.
int BsVConnHnd_T
virtual connection handle type
int ClientSendVErrorRsp(BsProxyClientHnd_T hndClient, BsTid_T uTid, int nECode, const char *sErrFmt, va_list ap)
Send va_list error response to the client.
INLINE_IN_H const char * ClientThisHasName(BsProxyClientCtl_T *pClient)
Get this <b><i>BotSense</i></b> client official name.
#define BSPROXY_RSPERR_EMSG_LEN