Skip to content

Commit 44181e1

Browse files
authored
Merge pull request #210 from CESNET/nemea++
unirec: add unirec++ helper for C++
2 parents bbd1854 + 01d0686 commit 44181e1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+2288
-57
lines changed

common/Makefile.am

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,6 @@ endif
9090
deb-clean:
9191
rm -rf nemea-common*.build nemea-common*.changes nemea-common*.deb nemea-common-dev_*.deb nemea-common*.orig.tar.gz nemea-common-*.tar.gz nemea-common-@VERSION@
9292

93-
install-exec-hook:
94-
rm -f $(DESTDIR)$(libdir)/libnemea-common.la
95-
9693
clean-local: deb-clean rpm-clean
9794
rm -rf doc
9895

libtrap/src/Makefile.am

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
lib_LTLIBRARIES = libtrap.la
22
libtrap_la_LDFLAGS = -version-info 6:0:5
33
libtrap_la_SOURCES = trap.c trap_error.c ifc_dummy.c ifc_tcpip.c trap_internal.c ifc_tcpip_internal.h ifc_file.c ifc_file.h help_trapifcspec.c \
4-
trap_container.h trap_stack.h trap_ring_buffer.h trap_mbuf.h trap_mbuf.c ifc_service.h ifc_service.c ifc_service_internal.h \
4+
trap_container.h trap_stack.h trap_ring_buffer.h trap_mbuf.h trap_mbuf.c ifc_service.h ifc_service.c ifc_service_internal.h \
55
third-party/libjansson/dump.c \
66
third-party/libjansson/error.c \
77
third-party/libjansson/hashtable.c \

unirec/Doxyfile.in

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,9 @@ WARN_LOGFILE =
9797
#---------------------------------------------------------------------------
9898
# Configuration options related to the input files
9999
#---------------------------------------------------------------------------
100-
INPUT = ./ doc/
100+
INPUT = ./ ./unirec++/ ./include/unirec/ ./include/unirec++/ doc/
101101
INPUT_ENCODING = UTF-8
102-
FILE_PATTERNS = *.c *.h *.txt *.md
102+
FILE_PATTERNS = *.c *.h *.cpp *.hpp *.txt *.md
103103
RECURSIVE = NO
104104
EXCLUDE =
105105
EXCLUDE_SYMLINKS = NO

unirec/Makefile.am

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,22 @@
11
ACLOCAL_AMFLAGS=-I m4
2-
DIST_SUBDIRS = tests
2+
DIST_SUBDIRS = include . unirec++ tests
3+
SUBDIRS = include . unirec++
34

45
if ENABLE_TESTS
5-
SUBDIRS= . tests
6+
SUBDIRS += tests
67
endif
78

89
RPMDIR=RPMBUILD
910

10-
BUILT_SOURCES=ur_values.h ur_values.c ur_values.py
11-
12-
ur_values.h: ur_values.sh
13-
${top_srcdir}/ur_values.sh -i ${top_srcdir}
14-
15-
ur_values.c: ur_values.h
16-
17-
ur_values.py: ur_values.h
18-
19-
2011
lib_LTLIBRARIES=libunirec.la
12+
libunirec_la_CPPFLAGS=-I${srcdir}/include
2113
libunirec_la_CFLAGS=-fPIC
2214
libunirec_la_LDFLAGS=-static -ltrap
23-
libunirec_la_SOURCES=unirec.c unirec.h ur_values.c ur_values.h inline.h ipaddr.h macaddr.h links.h ur_time.h unirec2csv.h unirec2csv.c ip_prefix_search.c ipps_internal.h
15+
libunirec_la_SOURCES=unirec.c unirec2csv.c ip_prefix_search.c ipps_internal.h
2416

2517
pkgconfigdir = $(libdir)/pkgconfig
2618
pkgconfig_DATA = unirec.pc
2719

28-
unirecincludedir=$(includedir)/unirec
29-
unirecinclude_HEADERS=unirec.h \
30-
inline.h \
31-
ipaddr.h \
32-
macaddr.h \
33-
links.h \
34-
ur_time.h \
35-
unirec2csv.h \
36-
ip_prefix_search.h \
37-
ur_values.h
38-
3920
bin_SCRIPTS=ur_values.sh ur_processor.sh
4021

4122
EXTRA_DIST=values ur_values.sh ur_processor.sh \
@@ -84,9 +65,6 @@ endif
8465
deb-clean:
8566
rm -rf unirec_*.build unirec_*.changes unirec_*.deb unirec-dev_*.deb unirec_*.orig.tar.gz unirec-*.tar.gz unirec-@VERSION@
8667

87-
install-exec-hook:
88-
rm -f $(DESTDIR)$(libdir)/libunirec.la
89-
9068
clean-local: rpm-clean deb-clean
9169
find \( -name ur_values.c -o -name ur_values.h -o -name ur_values.py \) -exec rm -f {} + || true
9270
find \( -name fields.c -o -name fields.h \) -exec rm -f {} + || true
@@ -97,7 +75,8 @@ coverage: check
9775
genhtml coverage.info --output-directory out 2>/dev/null || echo "Skipped coverage analysis"
9876

9977
install-exec-hook:
100-
rm -f $(DESTDIR)$(libdir)/libunirec.la
78+
rm -f $(DESTDIR)$(libdir)/libunirec.la $(DESTDIR)$(libdir)/libunirec++.la
10179

10280
uninstall-hook:
103-
rm -f $(DESTDIR)$(libdir)/libunirec.la $(DESTDIR)$(libdir)/libunirec.a
81+
rm -f $(DESTDIR)$(libdir)/libunirec.la $(DESTDIR)$(libdir)/libunirec++.la $(DESTDIR)$(libdir)/libunirec.a $(DESTDIR)$(libdir)/libunirec++.a $(DESTDIR)$(libdir)/libunirec++.so.*
82+

unirec/configure.ac

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33

44
AC_PREREQ([2.63])
55
AC_INIT([unirec], [2.9.7], [[email protected]])
6-
AC_CONFIG_SRCDIR([unirec.h])
6+
AC_CONFIG_SRCDIR([unirec.c])
77
AC_CONFIG_HEADERS([config.h])
8-
AM_INIT_AUTOMAKE([silent-rules])
8+
AM_INIT_AUTOMAKE([subdir-objects silent-rules])
99
AM_SILENT_RULES([yes])
10-
RELEASE=1
10+
RELEASE=99
1111
AC_SUBST(RELEASE)
1212
USERNAME=`git config --get user.name`
1313
USERMAIL=`git config --get user.email`
@@ -22,10 +22,10 @@ AC_ARG_ENABLE([debug],
2222
[Enable build with debug symbols and without optimizations.]),
2323
[if test "$enableval" = "yes"; then
2424
CFLAGS="-std=gnu11 -Wall -g -O0 -fcommon $CFLAGS"
25-
CXXFLAGS="-std=gnu++11 -Wall -g -O0 $CXXFLAGS"
25+
CXXFLAGS="-std=c++17 -Wall -g -O0 $CXXFLAGS"
2626
fi],
2727
[CFLAGS="-std=gnu11 -Wall -g -O3 -fcommon $CFLAGS"
28-
CXXFLAGS="-std=gnu++11 -Wall -g -O3 $CXXFLAGS"])
28+
CXXFLAGS="-std=c++17 -Wall -g -O3 $CXXFLAGS"])
2929
LT_INIT()
3030
# Checks for programs.
3131
AM_PROG_CC_C_O
@@ -99,6 +99,11 @@ fi
9999

100100
AC_CONFIG_FILES([Makefile
101101
unirec.pc
102+
include/Makefile
103+
include/unirec/Makefile
104+
include/unirec++/Makefile
105+
unirec++/unirec++.pc
106+
unirec++/Makefile
102107
unirec.spec
103108
Doxyfile
104109
tests/Makefile])

unirec/include/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
SUBDIRS = unirec unirec++
2+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
unirecppincludedir=$(includedir)/unirec++
2+
unirecppinclude_HEADERS=bidirectionalInterface.hpp \
3+
inputInterface.hpp \
4+
ipAddress.hpp \
5+
macAddress.hpp \
6+
outputInterface.hpp \
7+
trapModuleInfo.hpp \
8+
unirecArray.hpp \
9+
unirecException.hpp \
10+
unirec.hpp \
11+
unirecRecord.hpp \
12+
unirecRecordView.hpp \
13+
unirecTypes.hpp \
14+
unirecTypeTraits.hpp \
15+
urTime.hpp
16+
17+
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
/**
2+
* @file
3+
* @author Pavel Siska <[email protected]>
4+
* @brief Defines a bidirectional interface for sending and receiving unirec records using the TRAP
5+
* interface provided by the UniRec library. This class provides a simple and easy-to-use
6+
* bidirectional interface for sending and receiving unirec records with the SAME format. It wraps
7+
* the TRAP interface provided by the UniRec library and includes methods for sending and receiving
8+
* records, changing the record template, setting timeouts, and more.
9+
*
10+
* SPDX-License-Identifier: BSD-3-Clause
11+
*/
12+
13+
#pragma once
14+
15+
#include "unirecException.hpp"
16+
#include "unirecRecord.hpp"
17+
#include "unirecRecordView.hpp"
18+
19+
#include <optional>
20+
#include <stdexcept>
21+
#include <string>
22+
#include <unirec/unirec.h>
23+
24+
namespace NemeaPlusPlus {
25+
26+
/**
27+
* @brief A class that provides a bidirectional interface for sending and receiving unirec records.
28+
*
29+
* This class wraps the TRAP interface provided by the UniRec library to provide a simple
30+
* and easy-to-use bidirectional interface for sending and receiving unirec records with the SAME
31+
* FORMAT.
32+
*/
33+
class UnirecBidirectionalInterface {
34+
public:
35+
/**
36+
* @brief Receives data from the interface and returns an optional UnirecRecordView object.
37+
*
38+
* If data is received successfully, an UnirecRecordView object is returned that provides a view
39+
* into the received data. If no data is available or a timeout occurs, std::nullopt is
40+
* returned.
41+
*
42+
* @return An optional UnirecRecordView object.
43+
* @throws EoFException if the end of the input stream is reached.
44+
* @throws FormatChangeException if the record format changes.
45+
*/
46+
std::optional<UnirecRecordView> receive();
47+
48+
/**
49+
* @brief Sends a UniRec record through the Trap interface.
50+
*
51+
* @param unirecRecord the Unirec record to send
52+
* @throws std::runtime_error if an error occurs while sending the record
53+
* @return true if the record was sent successfully, false if a timeout occurred
54+
*/
55+
bool send(UnirecRecord& unirecRecord) const;
56+
57+
/**
58+
* @brief Sends a UniRec record view through the Trap interface.
59+
*
60+
* @param unirecRecordView The UniRec record view to send.
61+
* @throws std::runtime_error if an error occurs while sending the record
62+
* @return true if the record was sent successfully, false if a timeout occurred
63+
*/
64+
bool send(UnirecRecordView& unirecRecordView) const;
65+
66+
/**
67+
* @brief Flushes any pending UniRec records in the Trap interface.
68+
*/
69+
void sendFlush() const;
70+
71+
/**
72+
* @brief Changes the Unirec template used by the bidirectional interface.
73+
*
74+
* This method should be called every time when the FormatChangeException is thrown.
75+
*
76+
* This method changes the UniRec record template used for decoding records received on the
77+
* interface.
78+
*
79+
* @throws std::runtime_error if the data format was not loaded or the template could not be
80+
* edited.
81+
*/
82+
void changeTemplate();
83+
84+
/**
85+
* @brief Sets the required Unirec format specification.
86+
*
87+
* This method sets the required Unirec format specification for the input interface.
88+
* Format: "uint64 BYTES, string SNI" (unirecDataType NAME)
89+
*
90+
* @param templateSpecification The required Unirec format specification.
91+
* @throws std::runtime_error if the required format could not be set.
92+
*/
93+
void setRequieredFormat(const std::string& templateSpecification);
94+
95+
/**
96+
* @brief Sets the receive timeout for the interface.
97+
* This method sets the timeout for receiving UniRec records on the interface. If no record is
98+
* received within the specified timeout, the receive method returns an empty optional.
99+
*
100+
* @param timeout The timeout value in microseconds.
101+
* - `TRAP_WAIT`: Blocking mode, wait for client's connection, for message transport to/from
102+
* internal system buffer.
103+
* - `TRAP_NO_WAIT`: Non-Blocking mode, do not wait ever.
104+
* - `timeout`: Wait max for specific time.
105+
*/
106+
void setReceiveTimeout(int timeout);
107+
108+
/**
109+
* @brief Sets the send timeout for the Trap interface.
110+
*
111+
* @param timeout The timeout value in microseconds.
112+
* - `TRAP_WAIT`: Blocking mode, wait for client's connection, for message transport
113+
* to/from internal system buffer.
114+
* - `TRAP_HALFWAIT`: Blocking only if any client is connected.
115+
* - `TRAP_NO_WAIT`: Non-Blocking mode, do not wait ever.
116+
* - `timeout`: Wait max for specific time.
117+
*/
118+
void setSendTimeout(int timeout);
119+
120+
/**
121+
* @brief Sets the autoflush timeout for the output Trap interface.
122+
*
123+
* @param timeout The timeout value in microseconds.
124+
* - `TRAP_NO_AUTO_FLUSH`: Do not autoflush trap buffers
125+
*/
126+
void setSendAutoflushTimeout(int timeout);
127+
128+
/**
129+
* @brief Disables sending an end-of-file marker on exit.
130+
*/
131+
void doNotsendEoFOnExit();
132+
133+
/**
134+
* @brief Gets the Unirec template used by the bidirectional interface.
135+
*
136+
* This method returns a pointer to the Unirec template used by the bidirectional interface.
137+
*
138+
* @return A pointer to the Unirec template used by the bidirectional interface.
139+
*/
140+
ur_template_t* getTemplate() const noexcept { return m_template; }
141+
142+
/**
143+
* @brief Destructor for the UnirecBidirectionalInterface class.
144+
*
145+
* Sends an end-of-file marker if m_sendEoFonExit is true, then frees the memory allocated
146+
* for the UniRec template.
147+
*/
148+
~UnirecBidirectionalInterface();
149+
150+
/**
151+
* @brief Gets a reference to the pre-allocated UniRec record for efficient use.
152+
*
153+
* This function provides access to the UniRec record instance that has already been
154+
* pre-allocated within the UnirecOutputInterface. It allows direct modification of the
155+
* record's fields before sending it through the TRAP interface. Using the pre-allocated record
156+
* can be faster compared to creating a new record, as there is no memory allocation involved.
157+
* However, please note that using the same record in a multithreaded context may not be
158+
* thread-safe.
159+
*
160+
* @note The record accessed through this function is specific to this instance of the
161+
* UnirecOutputInterface and should not be shared across multiple instances or threads.
162+
*
163+
* @return A reference to the pre-allocated UniRec record.
164+
*/
165+
UnirecRecord& getUnirecRecord() noexcept { return m_unirecRecord; }
166+
167+
/**
168+
* @brief Creates a new UniRec record with the specified maximum variable fields size.
169+
*
170+
* This function generates a fresh UniRec record instance, ready to be populated with data
171+
* before sending it through the TRAP interface. The maximum size of variable fields can be
172+
* specified to suit your data insertion needs. Unlike using the pre-allocated record with the
173+
* `getUnirecRecord` function, this function involves memory allocation and may have a slightly
174+
* higher overhead.
175+
*
176+
* @param maxVariableFieldsSize The maximum size for variable fields in the new UniRec record.
177+
* @return A newly created UnirecRecord instance.
178+
*/
179+
UnirecRecord createUnirecRecord(size_t maxVariableFieldsSize = UR_MAX_SIZE);
180+
181+
private:
182+
UnirecBidirectionalInterface(uint8_t inputInterfaceID, uint8_t outputInterfaceID);
183+
void handleReceiveErrorCodes(int errorCode) const;
184+
bool handleSendErrorCodes(int errorCode) const;
185+
bool isEoFReceived() const noexcept;
186+
void sendEoF() const;
187+
188+
ur_template_t* m_template;
189+
uint8_t m_inputInterfaceID;
190+
uint8_t m_outputInterfaceID;
191+
const void* m_prioritizedDataPointer;
192+
bool m_sendEoFonExit;
193+
bool m_EoFOnNextReceive;
194+
UnirecRecord m_unirecRecord;
195+
196+
friend class Unirec;
197+
};
198+
199+
} // namespace NemeaPlusPlus

0 commit comments

Comments
 (0)