59 #include "rnr/rnrconfig.h" 62 #include "rnr/dlistvoid.h" 63 #include "rnr/dliststr.h" 66 #include "rnr/sockset.h" 92 char *optarg,
void *pOptVal);
94 char *optarg,
void *pOptVal);
101 .synopsis =
"BotSense IP Proxy Server.",
103 "The BotSense Proxy Server (%P) provides an IP interace to any proxied " 104 "(pseudo) device. %P is multi-threaded by device to optimize client " 105 "responsiveness. For each (pseudo) device, there must exist a dynamically " 106 "linked library that %P will load as needed, plus a client side library. " 107 "The two libraries typically communicate through a defined set of NetMsgs " 108 "network messages. The Message Exchange Patterns (MEP) support by %P " 109 "are client request - server response and server output streaming " 112 "A wide range of RoadNarrows support robots use %P." 122 .long_opt =
"interface",
124 .has_arg = required_argument,
128 .fn_fmt = OptsFmtStr,
129 .arg_name =
"[<addr>][:<port>]",
130 .opt_desc =
"Server passive socket interface. The server will listen " 131 "on this interface to accept new incoming connection " 137 .long_opt =
"libpath",
139 .has_arg = required_argument,
143 .fn_fmt = OptsFmtStr,
145 .opt_desc =
"Add library directory path to search for dynamic linked " 159 #define SERVER_LOG_ERROR(ecode, efmt, ...) \ 160 LOGERROR("Server %s:%s(ecode=%d): " efmt, \ 162 bsStrError(ecode), (ecode>=0? ecode: -ecode), \ 171 #define SERVER_LOG_SYSERROR(efmt, ...) \ 172 LOGERROR("Server %s: %s(ecode=%d): %s(errno=%d)" efmt, \ 174 bsStrError(BS_ECODE_SYS), BS_ECODE_SYS, \ 175 strerror(errno), errno, ##__VA_ARGS__) 238 sd = SocketAttrGetSd(pSockClient);
295 if( (pVConn =
VConnGet(hndVConn)) != NULL )
329 if( pServer != NULL )
341 pthread_mutex_destroy(&pServer->
m_mutex);
356 const char *sLocalHostName,
363 bufName = NEWSTR(strlen(sPrefix)+16);
364 sprintf(bufName,
"%s_%d", sPrefix, nPort);
375 pthread_mutex_init(&pServer->
m_mutex, NULL);
379 LOGERROR(
"%s: Failed to open server listener socket.",
393 LOGERROR(
"%s: Failed to add server listener socket to set.",
465 hndClient, hndVConn, uTid, uMsgId,
491 struct timeval tvSelect;
492 Socket_T *pSockClient;
495 SockSetIter_T iterSockSet;
528 SOCK_SET_SELECTED, SOCK_IO_READ,
531 pSock=SockSetIterNext(&iterSockSet))
534 sd = SocketAttrGetSd(pSock);
539 if( sd == sdListener )
544 if( pSockClient == NULL )
555 "%s: Connection denied, maximum %d clients are " 556 "already registered.",
558 SocketClose(pSockClient);
559 SocketDelete(pSockClient);
566 LOGDIAG1(
"%s: %s: Connection accepted, client registered.",
568 LOGDIAG2(
"%s: %u registered clients.",
584 if( pClient == NULL )
587 "%d: No registered client for select().", sd);
598 LOGDIAG1(
"%s: %s: Connnection closed, client unregistered.",
602 LOGDIAG2(
"%s: %u registered clients.",
607 else if( nMsgLen > 0 )
618 SOCK_SET_SELECTED, SOCK_IO_WRITE,
621 pSock=SockSetIterNext(&iterSockSet))
623 sd = SocketAttrGetSd(pSock);
634 else if( nCntSd == 0 )
637 SOCK_SET_ACTIVE, SOCK_IO_READ,
640 pSock=SockSetIterNext(&iterSockSet))
643 sd = SocketAttrGetSd(pSock);
645 if( (sd != sdListener) && SocketStateIsErrored(pSock) )
648 LOGDIAG1(
"%s: %s: Connnection closed, client unregistered.",
651 LOGDIAG2(
"%s: %u registered clients.",
701 const char *sOptName,
711 sInet = new_strdup(optarg);
713 sSepField = strchr(sInet,
':');
719 nPort = (int)atol(sPort);
720 if( (nPort <= 0) || (nPort > 0xffff) )
722 OptsInvalid(
Argv0,
"'%s': Invalid '%s' argument port value.",
762 const char *sOptName,
784 Argv0 = basename(argv[0]);
814 LOGDIAG2(
"Warning: Currently only one listen interface is supported. " 815 "First I/F will be used.");
841 int main(
int argc,
char *argv[])
874 if( BsServerCtl == NULL )
888 LOGDIAG1(
"BotSense IP Proxy Server %s started",
ServerHasName());
893 return rc ==
BS_OK? 0: EC_ERROR;
int ClientRecvReq(BsProxyClientHnd_T hndClient, BsProxyMsgHdr_T *pMsgHdr, byte_t **addrBuf)
Receive a request message from client.
uint_t BsMsgId_T
client message id type [0-64k].
Socket_T * m_pServerSockListener
server listener socket
<b><i>BotSense</i></b> bsProxy IP server declarations.
BsProxyClientCtl_T * ClientAcquire(BsProxyClientHnd_T hndClient)
Acquire client, locking it from other threads.
#define BSPROXY_LISTEN_PORT_DFT
default bsProxy passive socket
static BsProxyServerCtl_T * BsProxyServerNew(const char *sPrefix, const char *sLocalHostName, int nPort)
Create new server control block.
BotSense client application - bsProxy server-terminated core messages.
void VConnRelease(BsVConnHnd_T hndVConn)
Release the locked virtual client.
static void ServerLock()
Lock server's mutual exclusion.
#define BS_ECODE_GEN
general, unspecified error
static BsProxyClientHnd_T BsProxyClientRegister(Socket_T *pSockClient)
Register a new client with the server.
BsProxyClientCtl_T * m_pServerRegClient[256]
registered clients
uint_t m_uServerRegClientCount
num of reg. clients
uint_t BsTid_T
client transaction id type [0-255].
Socket_T * m_pClientSock
client opened TCP socket
BsProxyThCtl_T * m_pThCtl
service thread
static void BsProxyDispatch(BsProxyClientHnd_T hndClient, BsProxyMsgHdr_T *pMsgHdr, byte_t bufReq[])
Dispatch client request.
static void BsProxyClientUnregister(BsProxyClientHnd_T hndClient)
Unregister a client with the server.
INLINE_IN_H int ServerHasPort()
Get the <b><i>BotSense</i></b> server's listening port.
static int BsProxyServer(BsProxyServerCtl_T *pServer)
Server mainloop.
#define BSPROXY_FD_SETSIZE
server socket set size
int VConnOpenServer()
Open special server virtual connection.
INLINE_IN_H const char * ServerHasName()
Get the <b><i>BotSense</i></b> server's official name.
static void BsProxyServerDelete(BsProxyServerCtl_T *pServer)
Delete a server control block.
#define BS_OK
not an error, success
static void MainEnv()
Get and set environment.
static int OptsCvtArgLibPath(const char *argv0, const char *sOptName, char *optarg, void *pOptVal)
Append command-line library search path option to list of search paths.
#define BSPROXY_VCONN_MOD_MIN
minimum module-specific handle value
INLINE_IN_H BsProxyServerCtl_T * ServerGet()
Get the <b><i>BotSense</i></b> server.
static DListStr_T * BsOptDListLibPath
list of lib search paths
#define BS_ECODE_BAD_VCONN_HND
bad virtual connection handle
#define BSPROXY_VCONN_MOD_MAX
maximum module-specific handle value
#define BS_ECODE_SYS
system (errno) error
int BsProxyClientHnd_T
bsProxy server client handle
int VConnClose(BsProxyClientHnd_T hndClient, BsVConnHnd_T hndVConn)
Close the virtual connection.
INLINE_IN_H BsProxyClientHnd_T ServerClientSd2Hnd(int sd)
Convert the <b><i>BotSense</i></b> server client socket descriptor to client handle.
void VConnOneTimeInit()
The bsProxy virtual connections one-time initialization.
INLINE_IN_H int ServerClientHnd2Sd(BsProxyClientHnd_T hndClient)
Convert the <b><i>BotSense</i></b> server client handle to client socket descriptor.
const char * m_sServerName
server's name
#define BSPROXY_REG_CLIENT_MAX
max number of simultaneous clients
#define BSPROXY_TUNE_T_SELECT
5.0s send select time out
pthread_mutex_t m_mutex
server mutex lock
static void MainCfg()
Get configuration.
static int OptsCvtArgInterface(const char *argv0, const char *sOptName, char *optarg, void *pOptVal)
Convert command-line listen interface option string to network name/number and port number...
BsProxyVConn_T * VConnAcquire(BsVConnHnd_T hndVConn)
Acquire virtual connection, locking it from other threads.
ushort_t m_hdrBodyLen
message body length
#define BSPROXY_SEND_ERROR_RSP(hndClient, hndVConn, uTid, ecode, efmt,...)
Log <b><i>BotSense</i></b> Error and Send Error Response.
ushort_t m_hdrMsgId
message id (vConnection unique)
disconnected or fatal, not deleted
static bool_t ServerTryLock()
Try to lock global mutual exclusion.
SockSet_T * m_pServerSockSet
server socket set
static void ServerUnlock()
Unlock server's mutual exclusion.
BsProxyClientHnd_T m_hndClient
proxied client handle
static const PkgInfo_T PkgInfo
#define SERVER_LOG_ERROR(ecode, efmt,...)
Log Proxy Server Specific Error.
INLINE_IN_H BsProxyClientCtl_T * ServerGetClient(BsProxyClientHnd_T hndClient)
Get the <b><i>BotSense</i></b> server client.
static OptsInfo_T BsProxyOptsInfo[]
static void MainInit(int argc, char *argv[])
Main initialization.
#define BS_ECODE_NO_RSRC
no resource available
#define BSPROXY_CHK_VCONN_HND(hndVConn)
uint_t m_uRefCnt
vconn ref count for this client
BsProxyVConn_T * VConnGet(BsVConnHnd_T hndVConn)
Get the virtual connection entry associated with the handle.
void ClientSetState(BsProxyClientCtl_T *pClient, BsProxyClientState_T eNewState)
Set client's state.
Package version information.
static DListVoid_T * BsOptDListListenIF
list of listen i/f's
#define SERVER_LOG_SYSERROR(efmt,...)
Log Proxy Server Specific System Error.
void ClientOneTimeInit()
The <b><i>BotSense</i></b> bsProxy server one-time client control initialization.
const char * Argv0
command base name
BotSense Proxy Message Header Structure.
BsProxyServerCtl_T * BsServerCtl
The server control block.
BsProxyClientCtl_T * ClientNew(Socket_T *pSockClient)
Create new client control structure.
#define BS_ECODE_SERVER_BAD_CLIENT
server detected bad client
int m_nPort
listen port number
static char * BsOptListenIFDft
default listen interface
#define BS_ECODE_INTERNAL
internal error (bug)
int ThQueue(BsProxyThCtl_T *pThCtl, BsProxyClientHnd_T hndClient, BsVConnHnd_T hndVConn, BsTid_T uTid, BsMsgId_T uMsgId, byte_t bufReq[], size_t uReqLen)
Queue a request for the given service thread.
byte_t m_hdrTid
transaction id
#define BS_ECODE_NO_VCONN
virtual connection not found
void ThOneTimeInit()
The service thread one-time global initialization.
#define BS_ECODE_SERVER_CONN_DENY
server denied connection
static OptsPgmInfo_T BsProxyPgmInfo
void ModOneTimeInit(DListStr_T *pDListLibPath)
The bsProxy interface module handling one-time initialization.
int main(int argc, char *argv[])
bsProxy main()
byte_t m_hdrVConn
virtual connection handle (server unique)
INLINE_IN_H const char * ClientHasName(BsProxyClientHnd_T hndClient)
Get the <b><i>BotSense</i></b> client official name.
void ClientDelete(BsProxyClientCtl_T *pClient)
Delete a client with the server.
int BsVConnHnd_T
virtual connection handle type
char * m_sAddr
listen local address or hostname
int m_nServerPort
server's listener port