1 /* msg.h
2 * Header file for all msg-related functions.
3 *
4 * File begun on 2007-07-13 by RGerhards (extracted from syslogd.c)
5 *
6 * Copyright 2007-2018 Rainer Gerhards and Adiscon GmbH.
7 *
8 * This file is part of the rsyslog runtime library.
9 *
10 * The rsyslog runtime library is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * The rsyslog runtime library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with the rsyslog runtime library. If not, see <http://www.gnu.org/licenses/>.
22 *
23 * A copy of the GPL can be found in the file "COPYING" in this distribution.
24 * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution.
25 */
26 #include "template.h" /* this is a quirk, but these two are too interdependant... */
27
28 #ifndef MSG_H_INCLUDED
29 #define MSG_H_INCLUDED 1
30
31 #include <pthread.h>
32 #include <libestr.h>
33 #include <stdint.h>
34 #include <json.h>
35 #include "obj.h"
36 #include "syslogd-types.h"
37 #include "template.h"
38 #include "atomic.h"
39
40 /* rgerhards 2004-11-08: The following structure represents a
41 * syslog message.
42 *
43 * Important Note:
44 * The message object is used for multiple purposes (once it
45 * has been created). Once created, it actully is a read-only
46 * object (though we do not specifically express this). In order
47 * to avoid multiple copies of the same object, we use a
48 * reference counter. This counter is set to 1 by the constructer
49 * and increased by 1 with a call to MsgAddRef(). The destructor
50 * checks the reference count. If it is more than 1, only the counter
51 * will be decremented. If it is 1, however, the object is actually
52 * destroyed. To make this work, it is vital that MsgAddRef() is
53 * called each time a "copy" is stored somewhere.
54 *
55 * WARNING: this structure is not calloc()ed, so be careful when
56 * adding new fields. You need to initialize them in
57 * msgBaseConstruct(). That function header comment also describes
58 * why this is the case.
59 */
60 struct msg {
61 BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */
62 flowControl_t flowCtlType;
63 /**< type of flow control we can apply, for enqueueing, needs not to be persisted because
64 once data has entered the queue, this property is no longer needed. */
65 pthread_mutex_t mut;
66 int iRefCount; /* reference counter (0 = unused) */
67 sbool bParseSuccess; /* set to reflect state of last executed higher level parser */
68 unsigned short iSeverity;/* the severity */
69 unsigned short iFacility;/* Facility code */
70 int offAfterPRI; /* offset, at which raw message WITHOUT PRI part starts in pszRawMsg */
71 int offMSG; /* offset at which the MSG part starts in pszRawMsg */
72 short iProtocolVersion;/* protocol version of message received 0 - legacy, 1 syslog-protocol) */
73 int msgFlags; /* flags associated with this message */
74 int iLenRawMsg; /* length of raw message */
75 int iLenMSG; /* Length of the MSG part */
76 int iLenTAG; /* Length of the TAG part */
77 int iLenHOSTNAME; /* Length of HOSTNAME */
78 int iLenPROGNAME; /* Length of PROGNAME (-1 = not yet set) */
79 uchar *pszRawMsg; /* message as it was received on the wire. This is important in case we
80 * need to preserve cryptographic verifiers. */
81 uchar *pszHOSTNAME; /* HOSTNAME from syslog message */
82 char *pszRcvdAt3164; /* time as RFC3164 formatted string (always 15 characters) */
83 char *pszRcvdAt3339; /* time as RFC3164 formatted string (32 characters at most) */
84 char *pszRcvdAt_MySQL; /* rcvdAt as MySQL formatted string (always 14 characters) */
85 char *pszRcvdAt_PgSQL; /* rcvdAt as PgSQL formatted string (always 21 characters) */
86 char *pszTIMESTAMP3164; /* TIMESTAMP as RFC3164 formatted string (always 15 characters) */
87 char *pszTIMESTAMP3339; /* TIMESTAMP as RFC3339 formatted string (32 characters at most) */
88 char *pszTIMESTAMP_MySQL;/* TIMESTAMP as MySQL formatted string (always 14 characters) */
89 char *pszTIMESTAMP_PgSQL;/* TIMESTAMP as PgSQL formatted string (always 21 characters) */
90 uchar *pszStrucData; /* STRUCTURED-DATA */
91 uint16_t lenStrucData; /* (cached) length of STRUCTURED-DATA */
92 cstr_t *pCSAPPNAME; /* APP-NAME */
93 cstr_t *pCSPROCID; /* PROCID */
94 cstr_t *pCSMSGID; /* MSGID */
95 prop_t *pInputName; /* input name property */
96 prop_t *pRcvFromIP; /* IP of system message was received from */
97 union {
98 prop_t *pRcvFrom;/* name of system message was received from */
99 struct sockaddr_storage *pfrominet; /* unresolved name */
100 } rcvFrom;
101
102 ruleset_t *pRuleset; /* ruleset to be used for processing this message */
103 time_t ttGenTime; /* time msg object was generated, same as tRcvdAt, but a Unix timestamp.
104 While this field looks redundant, it is required because a Unix timestamp
105 is used at later processing stages (namely in the output arena). Thanks to
106 the subleties of how time is defined, there is no reliable way to reconstruct
107 the Unix timestamp from the syslogTime fields (in practice, we may be close
108 enough to reliable, but I prefer to leave the subtle things to the OS, where
109 it obviously is solved in way or another...). */
110 struct syslogTime tRcvdAt;/* time the message entered this program */
111 struct syslogTime tTIMESTAMP;/* (parsed) value of the timestamp */
112 struct json_object *json;
113 struct json_object *localvars;
114 /* some fixed-size buffers to save malloc()/free() for frequently used fields (from the default templates) */
115 uchar szRawMsg[CONF_RAWMSG_BUFSIZE];
116 /* most messages are small, and these are stored here (without malloc/free!) */
117 uchar szHOSTNAME[CONF_HOSTNAME_BUFSIZE];
118 union {
119 uchar *ptr; /* pointer to progname value */
120 uchar szBuf[CONF_PROGNAME_BUFSIZE];
121 } PROGNAME;
122 union {
123 uchar *pszTAG; /* pointer to tag value */
124 uchar szBuf[CONF_TAG_BUFSIZE];
125 } TAG;
126 char pszTimestamp3164[CONST_LEN_TIMESTAMP_3164 + 1];
127 char pszTimestamp3339[CONST_LEN_TIMESTAMP_3339 + 1];
128 char pszTIMESTAMP_SecFrac[7];
129 /* Note: a pointer is 64 bits/8 char, so this is actually fewer than a pointer! */
130 char pszRcvdAt_SecFrac[7];
131 /* same as above. Both are fractional seconds for their respective timestamp */
132 char pszTIMESTAMP_Unix[12]; /* almost as small as a pointer! */
133 char pszRcvdAt_Unix[12];
134 char dfltTZ[8]; /* 7 chars max, less overhead than ptr! */
135 uchar *pszUUID; /* The message's UUID */
136 };
137
138
139 /* message flags (msgFlags), not an enum for historical reasons */
140 #define NOFLAG 0x000
141 /* no flag is set (to be used when a flag must be specified and none is required) */
142 #define INTERNAL_MSG 0x001
143 /* msg generated by logmsgInternal() --> special handling */
144 /* 0x002 not used because it was previously a known value - rgerhards, 2008-10-09 */
145 #define IGNDATE 0x004
146 /* ignore, if given, date in message and use date of reception as msg date */
147 #define MARK 0x008
148 /* this message is a mark */
149 #define NEEDS_PARSING 0x010
150 /* raw message, must be parsed before processing can be done */
151 #define PARSE_HOSTNAME 0x020
152 /* parse the hostname during message parsing */
153 #define NEEDS_DNSRESOL 0x040
154 /* fromhost address is unresolved and must be locked up via DNS reverse lookup first */
155 #define NEEDS_ACLCHK_U 0x080
156 /* check UDP ACLs after DNS resolution has been done in main queue consumer */
157 #define NO_PRI_IN_RAW 0x100
158 /* rawmsg does not include a PRI (Solaris!), but PRI is already set correctly in the msg object */
159 #define PRESERVE_CASE 0x200
160 /* preserve case in fromhost */
161
162 /* (syslog) protocol types */
163 #define MSG_LEGACY_PROTOCOL 0
164 #define MSG_RFC5424_PROTOCOL 1
165
166 #define MAX_VARIABLE_NAME_LEN 1024
167
168 /* function prototypes
169 */
170 PROTOTYPEObjClassInit(msg);
171 rsRetVal msgConstruct(smsg_t **ppThis);
172 rsRetVal msgConstructWithTime(smsg_t **ppThis, const struct syslogTime *stTime, const time_t ttGenTime);
173 rsRetVal msgConstructForDeserializer(smsg_t **ppThis);
174 rsRetVal msgConstructFinalizer(smsg_t *pThis);
175 rsRetVal msgDestruct(smsg_t **ppM);
176 smsg_t * MsgDup(smsg_t * pOld);
177 smsg_t *MsgAddRef(smsg_t *pM);
178 void setProtocolVersion(smsg_t *pM, int iNewVersion);
179 void MsgSetInputName(smsg_t *pMsg, prop_t*);
180 void MsgSetDfltTZ(smsg_t *pThis, char *tz);
181 rsRetVal MsgSetAPPNAME(smsg_t *pMsg, const char* pszAPPNAME);
182 rsRetVal MsgSetPROCID(smsg_t *pMsg, const char* pszPROCID);
183 rsRetVal MsgSetMSGID(smsg_t *pMsg, const char* pszMSGID);
184 void MsgSetParseSuccess(smsg_t *pMsg, int bSuccess);
185 void MsgSetTAG(smsg_t *pMsg, const uchar* pszBuf, const size_t lenBuf);
186 void MsgSetRuleset(smsg_t *pMsg, ruleset_t*);
187 rsRetVal MsgSetFlowControlType(smsg_t *pMsg, flowControl_t eFlowCtl);
188 rsRetVal MsgSetStructuredData(smsg_t *const pMsg, const char* pszStrucData);
189 rsRetVal MsgAddToStructuredData(smsg_t *pMsg, uchar *toadd, rs_size_t len);
190 void MsgGetStructuredData(smsg_t *pM, uchar **pBuf, rs_size_t *len);
191 rsRetVal msgSetFromSockinfo(smsg_t *pThis, struct sockaddr_storage *sa);
192 void MsgSetRcvFrom(smsg_t *pMsg, prop_t*);
193 void MsgSetRcvFromStr(smsg_t *const pMsg, const uchar* pszRcvFrom, const int, prop_t **);
194 rsRetVal MsgSetRcvFromIP(smsg_t *pMsg, prop_t*);
195 rsRetVal MsgSetRcvFromIPStr(smsg_t *const pThis, const uchar *psz, const int len, prop_t **ppProp);
196 void MsgSetHOSTNAME(smsg_t *pMsg, const uchar* pszHOSTNAME, const int lenHOSTNAME);
197 rsRetVal MsgSetAfterPRIOffs(smsg_t *pMsg, int offs);
198 void MsgSetMSGoffs(smsg_t *pMsg, int offs);
199 void MsgSetRawMsgWOSize(smsg_t *pMsg, char* pszRawMsg);
200 void ATTR_NONNULL() MsgSetRawMsg(smsg_t *const pThis, const char*const pszRawMsg, const size_t lenMsg);
201 rsRetVal MsgReplaceMSG(smsg_t *pThis, const uchar* pszMSG, int lenMSG);
202 uchar *MsgGetProp(smsg_t *pMsg, struct templateEntry *pTpe, msgPropDescr_t *pProp,
203 rs_size_t *pPropLen, unsigned short *pbMustBeFreed, struct syslogTime *ttNow);
204 uchar *getRcvFrom(smsg_t *pM);
205 void getTAG(smsg_t *pM, uchar **ppBuf, int *piLen, sbool);
206 const char *getTimeReported(smsg_t *pM, enum tplFormatTypes eFmt);
207 const char *getPRI(smsg_t *pMsg);
208 int getPRIi(const smsg_t * const pM);
209 int ATTR_NONNULL() getRawMsgLen(const smsg_t *const pMsg);
210 void getRawMsg(const smsg_t *pM, uchar **pBuf, int *piLen);
211 void ATTR_NONNULL() MsgTruncateToMaxSize(smsg_t *const pThis);
212 rsRetVal msgAddJSON(smsg_t *pM, uchar *name, struct json_object *json, int force_reset, int sharedReference);
213 rsRetVal msgAddMetadata(smsg_t *msg, uchar *metaname, uchar *metaval);
214 rsRetVal msgAddMultiMetadata(smsg_t *msg, const uchar **metaname, const uchar **metaval, const int count);
215 rsRetVal MsgGetSeverity(smsg_t *pThis, int *piSeverity);
216 rsRetVal MsgDeserialize(smsg_t *pMsg, strm_t *pStrm);
217 rsRetVal MsgSetPropsViaJSON(smsg_t *__restrict__ const pMsg, const uchar *__restrict__ const json);
218 rsRetVal MsgSetPropsViaJSON_Object(smsg_t *__restrict__ const pMsg, struct json_object *json);
219 const uchar* msgGetJSONMESG(smsg_t *__restrict__ const pMsg);
220
221 uchar *getMSG(smsg_t *pM);
222 const char *getHOSTNAME(smsg_t *pM);
223 char *getPROCID(smsg_t *pM, sbool bLockMutex);
224 char *getAPPNAME(smsg_t *pM, sbool bLockMutex);
225 void setMSGLen(smsg_t *pM, int lenMsg);
226 int getMSGLen(smsg_t *pM);
227 void getInputName(const smsg_t * const pM, uchar **ppsz, int *const plen);
228
229 int getHOSTNAMELen(smsg_t *pM);
230 uchar *getProgramName(smsg_t *pM, sbool bLockMutex);
231 uchar *getRcvFrom(smsg_t *pM);
232 rsRetVal propNameToID(const uchar *pName, propid_t *pPropID);
233 uchar *propIDToName(propid_t propID);
234 rsRetVal ATTR_NONNULL() msgCheckVarExists(smsg_t *const pMsg, msgPropDescr_t *pProp);
235 rsRetVal msgGetJSONPropJSON(smsg_t *pMsg, msgPropDescr_t *pProp, struct json_object **pjson);
236 rsRetVal msgGetJSONPropJSONorString(smsg_t * const pMsg, msgPropDescr_t *pProp, struct json_object **pjson,
237 uchar **pcstr);
238 rsRetVal getJSONPropVal(smsg_t *pMsg, msgPropDescr_t *pProp, uchar **pRes, rs_size_t *buflen,
239 unsigned short *pbMustBeFreed);
240 rsRetVal msgSetJSONFromVar(smsg_t *pMsg, uchar *varname, struct svar *var, int force_reset);
241 rsRetVal msgDelJSON(smsg_t *pMsg, uchar *varname);
242 rsRetVal jsonFind(smsg_t *const pMsg, msgPropDescr_t *pProp, struct json_object **jsonres);
243 struct json_object *jsonDeepCopy(struct json_object *src);
244
245 rsRetVal msgPropDescrFill(msgPropDescr_t *pProp, uchar *name, int nameLen);
246 void msgPropDescrDestruct(msgPropDescr_t *pProp);
247 void msgSetPRI(smsg_t *const __restrict__ pMsg, syslog_pri_t pri);
248
249 #define msgGetProtocolVersion(pM) ((pM)->iProtocolVersion)
250
251 /* returns non-zero if the message has structured data, 0 otherwise */
252 #define MsgHasStructuredData(pM) (((pM)->pszStrucData == NULL) ? 0 : 1)
253
254 /* ------------------------------ some inline functions ------------------------------ */
255
256 /* add Metadata to the message. This is stored in a special JSON
257 * container. Note that only string types are currently supported,
258 * what should pose absolutely no problem with the string-ish nature
259 * of rsyslog metadata.
260 * added 2015-01-09 rgerhards
261 */
262 /* set raw message size. This is needed in some cases where a trunctation is necessary
263 * but the raw message must not be newly set. The most important (and currently only)
264 * use case is if we remove trailing LF or NUL characters. Note that the size can NOT
265 * be extended, only shrunk!
266 * rgerhards, 2009-08-26
267 */
268 static inline void __attribute__((unused))
MsgSetRawMsgSize(smsg_t * const __restrict__ pMsg,const size_t newLen)269 MsgSetRawMsgSize(smsg_t *const __restrict__ pMsg, const size_t newLen)
270 {
271 assert(newLen <= (size_t) pMsg->iLenRawMsg);
272 pMsg->iLenRawMsg = newLen;
273 pMsg->pszRawMsg[newLen] = '\0';
274 }
275
276 /* get the ruleset that is associated with the ruleset.
277 * May be NULL. -- rgerhards, 2009-10-27
278 */
279 #define MsgGetRuleset(pMsg) ((pMsg)->pRuleset)
280
281 #endif /* #ifndef MSG_H_INCLUDED */
282