mirror of
https://github.com/rsyslog/rsyslog.git
synced 2025-12-20 07:20:41 +01:00
internal restructuring in omfwd.c - stage work for further modularization I
think I also fixed a bug as a side-effect - but not looked to much at
it
This commit is contained in:
parent
cebbf6d44e
commit
bcdb6dcfd7
326
omfwd.c
326
omfwd.c
@ -116,13 +116,172 @@ typedef struct _instanceData {
|
||||
#ifdef USE_GSSAPI
|
||||
static char *gss_base_service_name = NULL;
|
||||
static enum gss_mode_t {
|
||||
GSSMODE_NONE,
|
||||
GSSMODE_NONE, /* GSSAPI is NOT support (aka "we use plain tcp") - the default */
|
||||
GSSMODE_MIC,
|
||||
GSSMODE_ENC
|
||||
} gss_mode;
|
||||
#endif
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------- *
|
||||
* CODE THAT SHALL GO INTO ITS OWN MODULE *
|
||||
* ----------------------------------------------------------------- */
|
||||
|
||||
/* get the syslog forward port from selector_t. The passed in
|
||||
* struct must be one that is setup for forwarding.
|
||||
* rgerhards, 2007-06-28
|
||||
* We may change the implementation to try to lookup the port
|
||||
* if it is unspecified. So far, we use the IANA default auf 514.
|
||||
*/
|
||||
static char *getFwdSyslogPt(instanceData *pData)
|
||||
{
|
||||
assert(pData != NULL);
|
||||
if(pData->port == NULL)
|
||||
return("514");
|
||||
else
|
||||
return(pData->port);
|
||||
}
|
||||
|
||||
|
||||
/* Build frame based on selected framing */
|
||||
static rsRetVal TCPSendBldFrame(instanceData *pData, char **pmsg, size_t *plen, int *pbMustBeFreed, int *pbIsCompressed)
|
||||
{
|
||||
DEFiRet;
|
||||
TCPFRAMINGMODE framingToUse;
|
||||
size_t len;
|
||||
char *msg;
|
||||
char *buf = NULL; /* if this is non-NULL, it MUST be freed before return! */
|
||||
|
||||
assert(plen != NULL);
|
||||
assert(pbIsCompressed != NULL);
|
||||
assert(pbMustBeFreed != NULL);
|
||||
assert(pmsg != NULL);
|
||||
|
||||
msg = *pmsg;
|
||||
len = *plen;
|
||||
*pbIsCompressed = *msg == 'z'; /* cache this, so that we can modify the message buffer */
|
||||
/* select framing for this record. If we have a compressed record, we always need to
|
||||
* use octet counting because the data potentially contains all control characters
|
||||
* including LF.
|
||||
*/
|
||||
framingToUse = *pbIsCompressed ? TCP_FRAMING_OCTET_COUNTING : pData->tcp_framing;
|
||||
|
||||
/* now check if we need to add a line terminator. We need to
|
||||
* copy the string in memory in this case, this is probably
|
||||
* quicker than using writev and definitely quicker than doing
|
||||
* two socket calls.
|
||||
* rgerhards 2005-07-22
|
||||
*
|
||||
* Some messages already contain a \n character at the end
|
||||
* of the message. We append one only if we there is not
|
||||
* already one. This seems the best fit, though this also
|
||||
* means the message does not arrive unaltered at the final
|
||||
* destination. But in the spirit of legacy syslog, this is
|
||||
* probably the best to do...
|
||||
* rgerhards 2005-07-20
|
||||
*/
|
||||
|
||||
/* Build frame based on selected framing */
|
||||
if(framingToUse == TCP_FRAMING_OCTET_STUFFING) {
|
||||
if((*(msg+len-1) != '\n')) {
|
||||
/* in the malloc below, we need to add 2 to the length. The
|
||||
* reason is that we a) add one character and b) len does
|
||||
* not take care of the '\0' byte. Up until today, it was just
|
||||
* +1 , which caused rsyslogd to sometimes dump core.
|
||||
* I have added this comment so that the logic is not accidently
|
||||
* changed again. rgerhards, 2005-10-25
|
||||
*/
|
||||
if((buf = malloc((len + 2) * sizeof(char))) == NULL) {
|
||||
/* extreme mem shortage, try to solve
|
||||
* as good as we can. No point in calling
|
||||
* any alarms, they might as well run out
|
||||
* of memory (the risk is very high, so we
|
||||
* do NOT risk that). If we have a message of
|
||||
* more than 1 byte (what I guess), we simply
|
||||
* overwrite the last character.
|
||||
* rgerhards 2005-07-22
|
||||
*/
|
||||
if(len > 1) {
|
||||
*(msg+len-1) = '\n';
|
||||
} else {
|
||||
/* we simply can not do anything in
|
||||
* this case (its an error anyhow...).
|
||||
*/
|
||||
}
|
||||
} else {
|
||||
/* we got memory, so we can copy the message */
|
||||
memcpy(buf, msg, len); /* do not copy '\0' */
|
||||
*(buf+len) = '\n';
|
||||
*(buf+len+1) = '\0';
|
||||
msg = buf; /* use new one */
|
||||
++len; /* care for the \n */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Octect-Counting
|
||||
* In this case, we need to always allocate a buffer. This is because
|
||||
* we need to put a header in front of the message text
|
||||
*/
|
||||
char szLenBuf[16];
|
||||
int iLenBuf;
|
||||
|
||||
/* important: the printf-mask is "%d<sp>" because there must be a
|
||||
* space after the len!
|
||||
*//* The chairs of the IETF syslog-sec WG have announced that it is
|
||||
* consensus to do the octet count on the SYSLOG-MSG part only. I am
|
||||
* now changing the code to reflect this. Hopefully, it will not change
|
||||
* once again (there can no compatibility layer programmed for this).
|
||||
* To be on the save side, I just comment the code out. I mark these
|
||||
* comments with "IETF20061218".
|
||||
* rgerhards, 2006-12-19
|
||||
*/
|
||||
iLenBuf = snprintf(szLenBuf, sizeof(szLenBuf)/sizeof(char), "%d ", (int) len);
|
||||
/* IETF20061218 iLenBuf =
|
||||
snprintf(szLenBuf, sizeof(szLenBuf)/sizeof(char), "%d ", len + iLenBuf);*/
|
||||
|
||||
if((buf = malloc((len + iLenBuf) * sizeof(char))) == NULL) {
|
||||
/* we are out of memory. This is an extreme situation. We do not
|
||||
* call any alarm handlers because they most likely run out of mem,
|
||||
* too. We are brave enough to call debug output, though. Other than
|
||||
* that, there is nothing left to do. We can not sent the message (as
|
||||
* in case of the other framing, because the message is incomplete.
|
||||
* We could, however, send two chunks (header and text separate), but
|
||||
* that would cause a lot of complexity in the code. So we think it
|
||||
* is appropriate enough to just make sure we do not crash in this
|
||||
* very unlikely case. For this, it is justified just to loose
|
||||
* the message. Rgerhards, 2006-12-07
|
||||
*/
|
||||
dbgprintf("Error: out of memory when building TCP octet-counted "
|
||||
"frame. Message is lost, trying to continue.\n");
|
||||
ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
memcpy(buf, szLenBuf, iLenBuf); /* header */
|
||||
memcpy(buf + iLenBuf, msg, len); /* message */
|
||||
len += iLenBuf; /* new message size */
|
||||
msg = buf; /* set message buffer */
|
||||
}
|
||||
|
||||
/* frame building complete, on to actual sending */
|
||||
|
||||
*plen = len;
|
||||
if(buf == NULL) {
|
||||
/* msg not modified */
|
||||
*pbMustBeFreed = 0;
|
||||
} else {
|
||||
*pmsg = msg;
|
||||
*pbMustBeFreed = 1;
|
||||
}
|
||||
|
||||
finalize_it:
|
||||
return iRet;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------- *
|
||||
* END OF CODE THAT SHALL GO INTO ITS OWN MODULE *
|
||||
* ----------------------------------------------------------------- */
|
||||
|
||||
|
||||
BEGINcreateInstance
|
||||
CODESTARTcreateInstance
|
||||
ENDcreateInstance
|
||||
@ -466,25 +625,21 @@ static int TCPSendGSSSend(instanceData *pData, char *msg, size_t len)
|
||||
*/
|
||||
static int TCPSend(instanceData *pData, char *msg, size_t len)
|
||||
{
|
||||
DEFiRet;
|
||||
int retry = 0;
|
||||
int done = 0;
|
||||
int bIsCompressed;
|
||||
int lenSend;
|
||||
char *buf = NULL; /* if this is non-NULL, it MUST be freed before return! */
|
||||
TCPFRAMINGMODE framingToUse;
|
||||
int bMsgMustBeFreed = 0;/* must msg be freed at end of function? 0 - no, 1 - yes */
|
||||
|
||||
assert(pData != NULL);
|
||||
assert(msg != NULL);
|
||||
assert(len > 0);
|
||||
|
||||
bIsCompressed = *msg == 'z'; /* cache this, so that we can modify the message buffer */
|
||||
/* select framing for this record. If we have a compressed record, we always need to
|
||||
* use octet counting because the data potentially contains all control characters
|
||||
* including LF.
|
||||
*/
|
||||
framingToUse = bIsCompressed ? TCP_FRAMING_OCTET_COUNTING : pData->tcp_framing;
|
||||
iRet = TCPSendBldFrame(pData, &msg, &len, &bMsgMustBeFreed, &bIsCompressed);
|
||||
if(iRet != RS_RET_OK)
|
||||
return -1; /* TODO: change this code */
|
||||
|
||||
do { /* try to send message */
|
||||
while(1) { /* loop is broken when send succeeds or error occurs */
|
||||
if(pData->sock <= 0) {
|
||||
/* we need to open the socket first */
|
||||
# ifdef USE_GSSAPI
|
||||
@ -496,111 +651,12 @@ static int TCPSend(instanceData *pData, char *msg, size_t len)
|
||||
if((pData->sock = TCPSendCreateSocket(pData, pData->f_addr)) <= 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* now check if we need to add a line terminator. We need to
|
||||
* copy the string in memory in this case, this is probably
|
||||
* quicker than using writev and definitely quicker than doing
|
||||
* two socket calls.
|
||||
* rgerhards 2005-07-22
|
||||
*
|
||||
* Some messages already contain a \n character at the end
|
||||
* of the message. We append one only if we there is not
|
||||
* already one. This seems the best fit, though this also
|
||||
* means the message does not arrive unaltered at the final
|
||||
* destination. But in the spirit of legacy syslog, this is
|
||||
* probably the best to do...
|
||||
* rgerhards 2005-07-20
|
||||
*/
|
||||
|
||||
/* Build frame based on selected framing */
|
||||
if(framingToUse == TCP_FRAMING_OCTET_STUFFING) {
|
||||
if((*(msg+len-1) != '\n')) {
|
||||
if(buf != NULL)
|
||||
free(buf);
|
||||
/* in the malloc below, we need to add 2 to the length. The
|
||||
* reason is that we a) add one character and b) len does
|
||||
* not take care of the '\0' byte. Up until today, it was just
|
||||
* +1 , which caused rsyslogd to sometimes dump core.
|
||||
* I have added this comment so that the logic is not accidently
|
||||
* changed again. rgerhards, 2005-10-25
|
||||
*/
|
||||
if((buf = malloc((len + 2) * sizeof(char))) == NULL) {
|
||||
/* extreme mem shortage, try to solve
|
||||
* as good as we can. No point in calling
|
||||
* any alarms, they might as well run out
|
||||
* of memory (the risk is very high, so we
|
||||
* do NOT risk that). If we have a message of
|
||||
* more than 1 byte (what I guess), we simply
|
||||
* overwrite the last character.
|
||||
* rgerhards 2005-07-22
|
||||
*/
|
||||
if(len > 1) {
|
||||
*(msg+len-1) = '\n';
|
||||
} else {
|
||||
/* we simply can not do anything in
|
||||
* this case (its an error anyhow...).
|
||||
*/
|
||||
}
|
||||
} else {
|
||||
/* we got memory, so we can copy the message */
|
||||
memcpy(buf, msg, len); /* do not copy '\0' */
|
||||
*(buf+len) = '\n';
|
||||
*(buf+len+1) = '\0';
|
||||
msg = buf; /* use new one */
|
||||
++len; /* care for the \n */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Octect-Counting
|
||||
* In this case, we need to always allocate a buffer. This is because
|
||||
* we need to put a header in front of the message text
|
||||
*/
|
||||
char szLenBuf[16];
|
||||
int iLenBuf;
|
||||
|
||||
/* important: the printf-mask is "%d<sp>" because there must be a
|
||||
* space after the len!
|
||||
*//* The chairs of the IETF syslog-sec WG have announced that it is
|
||||
* consensus to do the octet count on the SYSLOG-MSG part only. I am
|
||||
* now changing the code to reflect this. Hopefully, it will not change
|
||||
* once again (there can no compatibility layer programmed for this).
|
||||
* To be on the save side, I just comment the code out. I mark these
|
||||
* comments with "IETF20061218".
|
||||
* rgerhards, 2006-12-19
|
||||
*/
|
||||
iLenBuf = snprintf(szLenBuf, sizeof(szLenBuf)/sizeof(char), "%d ", (int) len);
|
||||
/* IETF20061218 iLenBuf =
|
||||
snprintf(szLenBuf, sizeof(szLenBuf)/sizeof(char), "%d ", len + iLenBuf);*/
|
||||
|
||||
if((buf = malloc((len + iLenBuf) * sizeof(char))) == NULL) {
|
||||
/* we are out of memory. This is an extreme situation. We do not
|
||||
* call any alarm handlers because they most likely run out of mem,
|
||||
* too. We are brave enough to call debug output, though. Other than
|
||||
* that, there is nothing left to do. We can not sent the message (as
|
||||
* in case of the other framing, because the message is incomplete.
|
||||
* We could, however, send two chunks (header and text separate), but
|
||||
* that would cause a lot of complexity in the code. So we think it
|
||||
* is appropriate enough to just make sure we do not crash in this
|
||||
* very unlikely case. For this, it is justified just to loose
|
||||
* the message. Rgerhards, 2006-12-07
|
||||
*/
|
||||
dbgprintf("Error: out of memory when building TCP octet-counted "
|
||||
"frame. Message is lost, trying to continue.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(buf, szLenBuf, iLenBuf); /* header */
|
||||
memcpy(buf + iLenBuf, msg, len); /* message */
|
||||
len += iLenBuf; /* new message size */
|
||||
msg = buf; /* set message buffer */
|
||||
}
|
||||
|
||||
/* frame building complete, on to actual sending */
|
||||
|
||||
# ifdef USE_GSSAPI
|
||||
if(gss_mode != GSSMODE_NONE) {
|
||||
if(TCPSendGSSSend(pData, msg, len) == 0) {
|
||||
if(buf != NULL) {
|
||||
free(buf);
|
||||
if(bMsgMustBeFreed) {
|
||||
free(msg);
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
@ -609,8 +665,8 @@ static int TCPSend(instanceData *pData, char *msg, size_t len)
|
||||
/* try to recover */
|
||||
continue;
|
||||
} else {
|
||||
if(buf != NULL)
|
||||
free(buf);
|
||||
if(bMsgMustBeFreed)
|
||||
free(msg);
|
||||
dbgprintf("message not (tcp)send");
|
||||
return -1;
|
||||
}
|
||||
@ -622,8 +678,8 @@ static int TCPSend(instanceData *pData, char *msg, size_t len)
|
||||
bIsCompressed ? "***compressed***" : msg);
|
||||
if((unsigned)lenSend == len) {
|
||||
/* all well */
|
||||
if(buf != NULL) {
|
||||
free(buf);
|
||||
if(bMsgMustBeFreed) {
|
||||
free(msg);
|
||||
}
|
||||
return 0;
|
||||
} else if(lenSend != -1) {
|
||||
@ -633,8 +689,8 @@ static int TCPSend(instanceData *pData, char *msg, size_t len)
|
||||
*/
|
||||
dbgprintf("message not completely (tcp)send, ignoring %d\n", lenSend);
|
||||
usleep(1000); /* experimental - might be benefitial in this situation */
|
||||
if(buf != NULL)
|
||||
free(buf);
|
||||
if(bMsgMustBeFreed)
|
||||
free(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -642,8 +698,8 @@ static int TCPSend(instanceData *pData, char *msg, size_t len)
|
||||
case EMSGSIZE:
|
||||
dbgprintf("message not (tcp)send, too large\n");
|
||||
/* This is not a real error, so it is not flagged as one */
|
||||
if(buf != NULL)
|
||||
free(buf);
|
||||
if(bMsgMustBeFreed)
|
||||
free(msg);
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
@ -657,38 +713,22 @@ static int TCPSend(instanceData *pData, char *msg, size_t len)
|
||||
close(pData->sock);
|
||||
pData->sock = -1;
|
||||
} else {
|
||||
if(buf != NULL)
|
||||
free(buf);
|
||||
if(bMsgMustBeFreed)
|
||||
free(msg);
|
||||
return -1;
|
||||
}
|
||||
# ifdef USE_GSSAPI
|
||||
}
|
||||
# endif
|
||||
} while(!done); /* warning: do ... while() */
|
||||
}
|
||||
/*NOT REACHED*/
|
||||
|
||||
if(buf != NULL)
|
||||
free(buf);
|
||||
if(bMsgMustBeFreed)
|
||||
free(msg);
|
||||
return -1; /* only to avoid compiler warning! */
|
||||
}
|
||||
|
||||
|
||||
/* get the syslog forward port from selector_t. The passed in
|
||||
* struct must be one that is setup for forwarding.
|
||||
* rgerhards, 2007-06-28
|
||||
* We may change the implementation to try to lookup the port
|
||||
* if it is unspecified. So far, we use the IANA default auf 514.
|
||||
*/
|
||||
static char *getFwdSyslogPt(instanceData *pData)
|
||||
{
|
||||
assert(pData != NULL);
|
||||
if(pData->port == NULL)
|
||||
return("514");
|
||||
else
|
||||
return(pData->port);
|
||||
}
|
||||
|
||||
|
||||
/* try to resume connection if it is not ready
|
||||
* rgerhards, 2007-08-02
|
||||
*/
|
||||
@ -837,6 +877,7 @@ dbgprintf("UDP send socket not yet initialized, doing it now\n");
|
||||
pData->eDestState = eDestFORW_SUSP;
|
||||
iRet = RS_RET_SUSPENDED;
|
||||
}
|
||||
dbgprintf("forwarded\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1026,6 +1067,7 @@ ENDqueryEtryPt
|
||||
|
||||
|
||||
#ifdef USE_GSSAPI
|
||||
/* set a new GSSMODE based on config directive */
|
||||
static rsRetVal setGSSMode(void __attribute__((unused)) *pVal, uchar *mode)
|
||||
{
|
||||
if (!strcmp((char *) mode, "none")) {
|
||||
|
||||
@ -204,12 +204,6 @@ dbgprintf("imtcp: bEnableTCP %d\n", bEnableTCP);
|
||||
#endif
|
||||
if (bEnableTCP) {
|
||||
if(sockTCPLstn == NULL) {
|
||||
/* even when doing a re-init, we do not shut down and
|
||||
* re-open the TCP socket. That would break existing TCP
|
||||
* session, which we do not desire. Should at some time arise
|
||||
* need to do that, I recommend controlling that via a
|
||||
* user-selectable option. rgerhards, 2007-06-21
|
||||
*/
|
||||
# ifdef USE_GSSAPI
|
||||
if(bEnableTCP & ALLOWEDMETHOD_GSS) {
|
||||
if(TCPSessGSSInit()) {
|
||||
@ -230,13 +224,11 @@ ENDwillRun
|
||||
BEGINafterRun
|
||||
CODESTARTafterRun
|
||||
/* do cleanup here */
|
||||
dbgprintf("call clearAllowedSenders(0x%lx)\n", (unsigned long) pAllowedSenders_TCP);
|
||||
if (pAllowedSenders_TCP != NULL) {
|
||||
clearAllowedSenders (pAllowedSenders_TCP);
|
||||
pAllowedSenders_TCP = NULL;
|
||||
}
|
||||
#ifdef USE_GSSAPI
|
||||
dbgprintf("call clearAllowedSenders(0x%lx)\n", (unsigned long) pAllowedSenders_GSS);
|
||||
if (pAllowedSenders_GSS != NULL) {
|
||||
clearAllowedSenders (pAllowedSenders_GSS);
|
||||
pAllowedSenders_GSS = NULL;
|
||||
@ -290,8 +282,6 @@ CODESTARTmodInit
|
||||
*ipIFVersProvided = 1; /* so far, we only support the initial definition */
|
||||
CODEmodInit_QueryRegCFSLineHdlr
|
||||
/* register config file handlers */
|
||||
//CHKiRet(omsdRegCFSLineHdlr((uchar *)"omitlocallogging", 0, eCmdHdlrBinary,
|
||||
// NULL, &bOmitLocalLogging, STD_LOADABLE_MODULE_ID));
|
||||
#if defined(USE_GSSAPI)
|
||||
CHKiRet(regCfSysLineHdlr((uchar *)"gsslistenservicename", 0, eCmdHdlrGetWord, NULL, &gss_listen_service_name, NULL));
|
||||
#endif
|
||||
|
||||
@ -744,6 +744,7 @@ int TCPSessDataRcvd(int iTCPSess, char *pData, int iLen)
|
||||
|
||||
|
||||
#ifdef USE_GSSAPI
|
||||
/* returns 0 if all went OK, -1 if it failed */
|
||||
int TCPSessGSSInit(void)
|
||||
{
|
||||
gss_buffer_desc name_buf;
|
||||
@ -775,6 +776,7 @@ int TCPSessGSSInit(void)
|
||||
}
|
||||
|
||||
|
||||
/* returns 0 if all went OK, -1 if it failed */
|
||||
int TCPSessGSSAccept(int fd)
|
||||
{
|
||||
gss_buffer_desc send_tok, recv_tok;
|
||||
@ -937,6 +939,7 @@ int TCPSessGSSAccept(int fd)
|
||||
}
|
||||
|
||||
|
||||
/* returns: ? */
|
||||
int TCPSessGSSRecv(int iSess, void *buf, size_t buf_len)
|
||||
{
|
||||
gss_buffer_desc xmit_buf, msg_buf;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user