summaryrefslogtreecommitdiffstats
path: root/tcpsrv.c
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2008-03-03 09:04:59 +0000
committerRainer Gerhards <rgerhards@adiscon.com>2008-03-03 09:04:59 +0000
commit42730360196f1aaafaebb955c1a0a66a185e61ec (patch)
treea372aed0c06905d230ed383249028aa220417a1e /tcpsrv.c
parent9d8eb28ebd941694d8dcbc66c6e5c80cf90a206d (diff)
downloadrsyslog-42730360196f1aaafaebb955c1a0a66a185e61ec.tar.gz
rsyslog-42730360196f1aaafaebb955c1a0a66a185e61ec.tar.xz
rsyslog-42730360196f1aaafaebb955c1a0a66a185e61ec.zip
made imgssapi compile
Diffstat (limited to 'tcpsrv.c')
-rw-r--r--tcpsrv.c150
1 files changed, 98 insertions, 52 deletions
diff --git a/tcpsrv.c b/tcpsrv.c
index 0453b2d4..efc582de 100644
--- a/tcpsrv.c
+++ b/tcpsrv.c
@@ -72,10 +72,6 @@ DEFobjStaticHelpers
DEFobjCurrIf(conf)
DEFobjCurrIf(tcps_sess)
-static char *TCPLstnPort = "0"; /* read-only after startup */
-static tcps_sess_t **pTCPSessions;
-/* The thread-safeness of the sesion table is doubtful */
-
/* code to free all sockets within a socket table.
@@ -129,10 +125,10 @@ configureTCPListen(tcpsrv_t *pThis, char *cOptarg)
}
if( i >= 0 && i <= 65535) {
- TCPLstnPort = cOptarg;
+ pThis->TCPLstnPort = cOptarg;
} else {
logerrorSz("Invalid TCP listen port %s - changed to 514.\n", cOptarg);
- TCPLstnPort = "514";
+ pThis->TCPLstnPort = "514";
}
}
@@ -172,10 +168,10 @@ TCPSessTblInit(tcpsrv_t *pThis)
DEFiRet;
ISOBJ_TYPE_assert(pThis, tcpsrv);
- assert(pTCPSessions == NULL);
+ assert(pThis->pSessions == NULL);
dbgprintf("Allocating buffer for %d TCP sessions.\n", pThis->iSessMax);
- if((pTCPSessions = (tcps_sess_t **) calloc(pThis->iSessMax, sizeof(tcps_sess_t *))) == NULL) {
+ if((pThis->pSessions = (tcps_sess_t **) calloc(pThis->iSessMax, sizeof(tcps_sess_t *))) == NULL) {
dbgprintf("Error: TCPSessInit() could not alloc memory for TCP session table.\n");
ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
}
@@ -197,7 +193,7 @@ TCPSessTblFindFreeSpot(tcpsrv_t *pThis)
ISOBJ_TYPE_assert(pThis, tcpsrv);
for(i = 0 ; i < pThis->iSessMax ; ++i) {
- if(pTCPSessions[i] == NULL)
+ if(pThis->pSessions[i] == NULL)
break;
}
@@ -220,7 +216,7 @@ TCPSessGetNxtSess(tcpsrv_t *pThis, int iCurr)
ISOBJ_TYPE_assert(pThis, tcpsrv);
for(i = iCurr + 1 ; i < pThis->iSessMax ; ++i)
- if(pTCPSessions[i] != NULL)
+ if(pThis->pSessions[i] != NULL)
break;
return((i < pThis->iSessMax) ? i : -1);
@@ -238,20 +234,20 @@ static void deinit_tcp_listener(tcpsrv_t *pThis)
int iTCPSess;
ISOBJ_TYPE_assert(pThis, tcpsrv);
- assert(pTCPSessions != NULL);
+ assert(pThis->pSessions != NULL);
/* close all TCP connections! */
iTCPSess = TCPSessGetNxtSess(pThis, -1);
while(iTCPSess != -1) {
- tcps_sess.Destruct(&pTCPSessions[iTCPSess]);
+ tcps_sess.Destruct(&pThis->pSessions[iTCPSess]);
/* now get next... */
iTCPSess = TCPSessGetNxtSess(pThis, iTCPSess);
}
/* we are done with the session table - so get rid of it...
*/
- free(pTCPSessions);
- pTCPSessions = NULL; /* just to make sure... */
+ free(pThis->pSessions);
+ pThis->pSessions = NULL; /* just to make sure... */
/* finally close the listen sockets themselfs */
freeAllSockets(&pThis->pSocksLstn);
@@ -274,30 +270,28 @@ static int *create_tcp_socket(tcpsrv_t *pThis)
{
struct addrinfo hints, *res, *r;
int error, maxs, *s, *socks, on = 1;
-DEFiRet;
ISOBJ_TYPE_assert(pThis, tcpsrv);
- if(!strcmp(TCPLstnPort, "0"))
- TCPLstnPort = "514";
+ if(!strcmp(pThis->TCPLstnPort, "0"))
+ pThis->TCPLstnPort = "514";
/* use default - we can not do service db update, because there is
* no IANA-assignment for syslog/tcp. In the long term, we might
* re-use RFC 3195 port of 601, but that would probably break to
* many existing configurations.
* rgerhards, 2007-06-28
*/
- dbgprintf("creating tcp socket on port %s\n", TCPLstnPort);
+ dbgprintf("creating tcp socket on port %s\n", pThis->TCPLstnPort);
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
hints.ai_family = family;
hints.ai_socktype = SOCK_STREAM;
- error = getaddrinfo(NULL, TCPLstnPort, &hints, &res);
+ error = getaddrinfo(NULL, pThis->TCPLstnPort, &hints, &res);
if(error) {
logerror((char*) gai_strerror(error));
return NULL;
}
-RUNLOG;
/* Count max number of sockets we may open */
for (maxs = 0, r = res; r != NULL ; r = r->ai_next, maxs++)
@@ -308,7 +302,6 @@ RUNLOG;
freeaddrinfo(res);
return NULL;
}
-RUNLOG;
*socks = 0; /* num of sockets counter at start of array */
s = socks + 1;
@@ -346,7 +339,6 @@ RUNLOG;
/* We need to enable BSD compatibility. Otherwise an attacker
* could flood our log files by sending us tons of ICMP errors.
*/
-RUNLOG;
#ifndef BSD
if (should_use_so_bsdcompat()) {
if (setsockopt(*s, SOL_SOCKET, SO_BSDCOMPAT,
@@ -369,7 +361,6 @@ RUNLOG;
*s = -1;
continue;
}
-RUNLOG;
if( listen(*s,pThis->iSessMax / 10 + 5) < 0) {
/* If the listen fails, it most probably fails because we ask
@@ -390,7 +381,6 @@ RUNLOG;
(*socks)++;
s++;
}
-RUNLOG;
if(res != NULL)
freeaddrinfo(res);
@@ -406,7 +396,6 @@ RUNLOG;
return(NULL);
}
-RUNLOG;
/* OK, we had success. Now it is also time to
* initialize our connections
*/
@@ -420,7 +409,6 @@ RUNLOG;
return(NULL);
}
-dbgprintf("TCP socket(s) successfully created.\n");
return(socks);
}
@@ -428,9 +416,12 @@ dbgprintf("TCP socket(s) successfully created.\n");
/* Accept new TCP connection; make entry in session table. If there
* is no more space left in the connection table, the new TCP
* connection is immediately dropped.
+ * ppSess has a pointer to the newly created session, if it succeds.
+ * If it does not succeed, no session is created and ppSess is
+ * undefined. -- rgerhards, 2008-03-02
*/
static int
-SessAccept(tcpsrv_t *pThis, int fd)
+SessAccept(tcpsrv_t *pThis, tcps_sess_t **ppSess, int fd)
{
DEFiRet;
@@ -456,8 +447,13 @@ SessAccept(tcpsrv_t *pThis, int fd)
logerror("too many tcp sessions - dropping incoming request");
close(newConn);
return -1;
+ } else {
+ /* we found a free spot and can construct our session object */
+ CHKiRet(tcps_sess.Construct(&pThis->pSessions[iSess]));
}
+ *ppSess = pThis->pSessions[iSess];
+
/* OK, we have a "good" index... */
/* get the host name */
if(cvthname(&addr, fromHost, fromHostFQDN) != RS_RET_OK) {
@@ -475,7 +471,8 @@ SessAccept(tcpsrv_t *pThis, int fd)
* configured to do this).
* rgerhards, 2005-09-26
*/
- if(!pThis->pIsPermittedHost((struct sockaddr*) &addr, (char*) fromHostFQDN))
+ if(!pThis->pIsPermittedHost((struct sockaddr*) &addr, (char*) fromHostFQDN,
+ pThis->pUsr, pThis->pSessions[iSess]->pUsr))
{
dbgprintf("%s is not an allowed sender\n", (char *) fromHostFQDN);
if(option_DisallowWarning) {
@@ -489,16 +486,19 @@ SessAccept(tcpsrv_t *pThis, int fd)
/* OK, we have an allowed sender, so let's continue */
/* we first need to construct a new session object */
- CHKiRet(tcps_sess.Construct(&pTCPSessions[iSess]));
- CHKiRet(tcps_sess.SetHost(pTCPSessions[iSess], fromHost));
- CHKiRet(tcps_sess.SetSock(pTCPSessions[iSess], newConn));
- CHKiRet(tcps_sess.SetMsgIdx(pTCPSessions[iSess], 0));
- CHKiRet(tcps_sess.ConstructFinalize(pTCPSessions[iSess]));
+ CHKiRet(tcps_sess.SetTcpsrv(pThis->pSessions[iSess], pThis));
+ CHKiRet(tcps_sess.SetHost(pThis->pSessions[iSess], fromHost));
+ CHKiRet(tcps_sess.SetSock(pThis->pSessions[iSess], newConn));
+ CHKiRet(tcps_sess.SetMsgIdx(pThis->pSessions[iSess], 0));
+ CHKiRet(tcps_sess.ConstructFinalize(pThis->pSessions[iSess]));
finalize_it:
RUNLOG_VAR("%d", iRet);
- if(iRet != RS_RET_OK)
+ if(iRet != RS_RET_OK) {
+ if(pThis->pSessions[iSess] != NULL)
+ tcps_sess.Destruct(&pThis->pSessions[iSess]);
iSess = -1; // TODO: change this to be fully iRet compliant ;)
+ }
ENDfunc
return iSess;
@@ -516,6 +516,7 @@ Run(tcpsrv_t *pThis)
int i;
int iTCPSess;
fd_set readfds;
+ tcps_sess_t *pNewSess;
ISOBJ_TYPE_assert(pThis, tcpsrv);
@@ -546,7 +547,7 @@ Run(tcpsrv_t *pThis)
iTCPSess = TCPSessGetNxtSess(pThis, -1);
while(iTCPSess != -1) {
int fdSess;
- fdSess = pTCPSessions[iTCPSess]->sock; // TODO: NOT CLEAN!, use method
+ fdSess = pThis->pSessions[iTCPSess]->sock; // TODO: NOT CLEAN!, use method
dbgprintf("Adding TCP Session %d\n", fdSess);
FD_SET(fdSess, &readfds);
if (fdSess>maxfds) maxfds=fdSess;
@@ -570,7 +571,7 @@ Run(tcpsrv_t *pThis)
for (i = 0; i < *pThis->pSocksLstn; i++) {
if (FD_ISSET(pThis->pSocksLstn[i+1], &readfds)) {
dbgprintf("New connect on TCP inetd socket: #%d\n", pThis->pSocksLstn[i+1]);
- pThis->pOnSessAccept(pThis, pThis->pSocksLstn[i+1]);
+ pThis->pOnSessAccept(pThis, &pNewSess, pThis->pSocksLstn[i+1]);
--nfds; /* indicate we have processed one */
}
}
@@ -580,31 +581,31 @@ Run(tcpsrv_t *pThis)
while(nfds && iTCPSess != -1) {
int fdSess;
int state;
- fdSess = pTCPSessions[iTCPSess]->sock; // TODO: not clean, use method
+ fdSess = pThis->pSessions[iTCPSess]->sock; // TODO: not clean, use method
if(FD_ISSET(fdSess, &readfds)) {
char buf[MAXLINE];
dbgprintf("tcp session socket with new data: #%d\n", fdSess);
/* Receive message */
- state = pThis->pRcvData(pTCPSessions[iTCPSess], buf, sizeof(buf));
+ state = pThis->pRcvData(pThis->pSessions[iTCPSess], buf, sizeof(buf));
if(state == 0) {
- pThis->pOnRegularClose(pTCPSessions[iTCPSess]);
- tcps_sess.Destruct(&pTCPSessions[iTCPSess]);
+ pThis->pOnRegularClose(pThis->pSessions[iTCPSess]);
+ tcps_sess.Destruct(&pThis->pSessions[iTCPSess]);
} else if(state == -1) {
logerrorInt("TCP session %d will be closed, error ignored\n", fdSess);
- pThis->pOnErrClose(pTCPSessions[iTCPSess]);
- tcps_sess.Destruct(&pTCPSessions[iTCPSess]);
+ pThis->pOnErrClose(pThis->pSessions[iTCPSess]);
+ tcps_sess.Destruct(&pThis->pSessions[iTCPSess]);
} else {
/* valid data received, process it! */
- if(tcps_sess.DataRcvd(pTCPSessions[iTCPSess], buf, state) == 0) {
+ if(tcps_sess.DataRcvd(pThis->pSessions[iTCPSess], buf, state) == 0) {
/* in this case, something went awfully wrong.
* We are instructed to terminate the session.
*/
logerrorInt("Tearing down TCP Session %d - see "
"previous messages for reason(s)\n",
iTCPSess);
- pThis->pOnErrClose(pTCPSessions[iTCPSess]);
- tcps_sess.Destruct(&pTCPSessions[iTCPSess]);
+ pThis->pOnErrClose(pThis->pSessions[iTCPSess]);
+ tcps_sess.Destruct(&pThis->pSessions[iTCPSess]);
}
}
--nfds; /* indicate we have processed one */
@@ -634,7 +635,7 @@ tcpsrvConstructFinalize(tcpsrv_t __attribute__((unused)) *pThis)
{
DEFiRet;
ISOBJ_TYPE_assert(pThis, tcpsrv);
- pThis->pSocksLstn = create_tcp_socket(pThis);
+ pThis->pSocksLstn = pThis->OpenLstnSocks(pThis);
RETiRet;
}
@@ -643,6 +644,9 @@ tcpsrvConstructFinalize(tcpsrv_t __attribute__((unused)) *pThis)
/* destructor for the tcpsrv object */
BEGINobjDestruct(tcpsrv) /* be sure to specify the object type also in END and CODESTART macros! */
CODESTARTobjDestruct(tcpsrv)
+ if(pThis->OnDestruct != NULL)
+ pThis->OnDestruct(pThis->pUsr);
+
deinit_tcp_listener(pThis);
ENDobjDestruct(tcpsrv)
@@ -654,7 +658,7 @@ ENDobjDebugPrint(tcpsrv)
/* set functions */
static rsRetVal
-SetCBIsPermittedHost(tcpsrv_t *pThis, int (*pCB)(struct sockaddr *addr, char *fromHostFQDN))
+SetCBIsPermittedHost(tcpsrv_t *pThis, int (*pCB)(struct sockaddr *addr, char *fromHostFQDN, void*, void*))
{
DEFiRet;
pThis->pIsPermittedHost = pCB;
@@ -678,7 +682,7 @@ SetCBOnListenDeinit(tcpsrv_t *pThis, int (*pCB)(void*))
}
static rsRetVal
-SetCBOnSessAccept(tcpsrv_t *pThis, rsRetVal (*pCB)(tcpsrv_t*,int))
+SetCBOnSessAccept(tcpsrv_t *pThis, rsRetVal (*pCB)(tcpsrv_t*, tcps_sess_t**, int))
{
DEFiRet;
pThis->pOnSessAccept = pCB;
@@ -686,6 +690,30 @@ SetCBOnSessAccept(tcpsrv_t *pThis, rsRetVal (*pCB)(tcpsrv_t*,int))
}
static rsRetVal
+SetCBOnDestruct(tcpsrv_t *pThis, rsRetVal (*pCB)(void*))
+{
+ DEFiRet;
+ pThis->OnDestruct = pCB;
+ RETiRet;
+}
+
+static rsRetVal
+SetCBOnSessConstructFinalize(tcpsrv_t *pThis, rsRetVal (*pCB)(void*))
+{
+ DEFiRet;
+ pThis->OnSessConstructFinalize = pCB;
+ RETiRet;
+}
+
+static rsRetVal
+SetCBOnSessDestruct(tcpsrv_t *pThis, rsRetVal (*pCB)(void*))
+{
+ DEFiRet;
+ pThis->pOnSessDestruct = pCB;
+ RETiRet;
+}
+
+static rsRetVal
SetCBOnRegularClose(tcpsrv_t *pThis, rsRetVal (*pCB)(tcps_sess_t*))
{
DEFiRet;
@@ -701,6 +729,22 @@ SetCBOnErrClose(tcpsrv_t *pThis, rsRetVal (*pCB)(tcps_sess_t*))
RETiRet;
}
+static rsRetVal
+SetCBOpenLstnSocks(tcpsrv_t *pThis, int* (*pCB)(tcpsrv_t*))
+{
+ DEFiRet;
+ pThis->OpenLstnSocks = pCB;
+ RETiRet;
+}
+
+static rsRetVal
+SetUsrP(tcpsrv_t *pThis, void *pUsr)
+{
+ DEFiRet;
+ pThis->pUsr = pUsr;
+ RETiRet;
+}
+
/* queryInterface function
@@ -717,10 +761,6 @@ CODESTARTobjQueryInterface(tcpsrv)
* work here (if we can support an older interface version - that,
* of course, also affects the "if" above).
*/
- //pIf->freeAllSockets = freeAllSockets;
- //pIf->configureTCPListen = configureTCPListen;
- //pIf->configureTCPListenSessMax = configureTCPListenSessMax;
- //pIf->TCPSessAccept = TCPSessAccept;
pIf->DebugPrint = tcpsrvDebugPrint;
pIf->Construct = tcpsrvConstruct;
pIf->ConstructFinalize = tcpsrvConstructFinalize;
@@ -728,12 +768,18 @@ CODESTARTobjQueryInterface(tcpsrv)
pIf->SessAccept = SessAccept;
pIf->configureTCPListen = configureTCPListen;
+ pIf->create_tcp_socket = create_tcp_socket;
pIf->Run = Run;
+ pIf->SetUsrP = SetUsrP;
pIf->SetCBIsPermittedHost = SetCBIsPermittedHost;
+ pIf->SetCBOpenLstnSocks = SetCBOpenLstnSocks;
pIf->SetCBRcvData = SetCBRcvData;
pIf->SetCBOnListenDeinit = SetCBOnListenDeinit;
pIf->SetCBOnSessAccept = SetCBOnSessAccept;
+ pIf->SetCBOnSessConstructFinalize = SetCBOnSessConstructFinalize;
+ pIf->SetCBOnSessDestruct = SetCBOnSessDestruct;
+ pIf->SetCBOnDestruct = SetCBOnDestruct;
pIf->SetCBOnRegularClose = SetCBOnRegularClose;
pIf->SetCBOnErrClose = SetCBOnErrClose;