1+ /* *
2+ * \file
3+ * \author Damir Zainullin <[email protected] > 4+ * \brief CacheOptParser implementation.
5+ */
6+ /*
7+ * Copyright (C) 2023 CESNET
8+ *
9+ * LICENSE TERMS
10+ *
11+ * Redistribution and use in source and binary forms, with or without
12+ * modification, are permitted provided that the following conditions
13+ * are met:
14+ * 1. Redistributions of source code must retain the above copyright
15+ * notice, this list of conditions and the following disclaimer.
16+ * 2. Redistributions in binary form must reproduce the above copyright
17+ * notice, this list of conditions and the following disclaimer in
18+ * the documentation and/or other materials provided with the
19+ * distribution.
20+ * 3. Neither the name of the Company nor the names of its contributors
21+ * may be used to endorse or promote products derived from this
22+ * software without specific prior written permission.
23+ */
24+
25+ #include " cacheOptParser.hpp"
26+
27+ #include < cstring>
28+ #include < ipfixprobe/plugin.hpp>
29+ #include < ipfixprobe/utils.hpp>
30+
31+ namespace ipxp {
32+
33+ #ifdef IPXP_FLOW_CACHE_SIZE
34+ static const uint32_t DEFAULT_FLOW_CACHE_SIZE = IPXP_FLOW_CACHE_SIZE;
35+ #else
36+ static const uint32_t DEFAULT_FLOW_CACHE_SIZE = 17 ; // 131072 records total
37+ #endif /* IPXP_FLOW_CACHE_SIZE */
38+
39+ #ifdef IPXP_FLOW_LINE_SIZE
40+ static const uint32_t DEFAULT_FLOW_LINE_SIZE = IPXP_FLOW_LINE_SIZE;
41+ #else
42+ static const uint32_t DEFAULT_FLOW_LINE_SIZE = 4 ; // 16 records per line
43+ #endif /* IPXP_FLOW_LINE_SIZE */
44+
45+ static const uint32_t DEFAULT_INACTIVE_TIMEOUT = 30 ;
46+ static const uint32_t DEFAULT_ACTIVE_TIMEOUT = 300 ;
47+
48+ static_assert (std::is_unsigned<decltype (DEFAULT_FLOW_CACHE_SIZE)>(), " Static checks of default cache sizes won't properly work without unsigned type." );
49+ static_assert (bitcount<decltype (DEFAULT_FLOW_CACHE_SIZE)>(-1 ) > DEFAULT_FLOW_CACHE_SIZE, " Flow cache size is too big to fit in variable!" );
50+ static_assert (bitcount<decltype (DEFAULT_FLOW_LINE_SIZE)>(-1 ) > DEFAULT_FLOW_LINE_SIZE, " Flow cache line size is too big to fit in variable!" );
51+
52+ static_assert (DEFAULT_FLOW_LINE_SIZE >= 1 , " Flow cache line size must be at least 1!" );
53+ static_assert (DEFAULT_FLOW_CACHE_SIZE >= DEFAULT_FLOW_LINE_SIZE, " Flow cache size must be at least cache line size!" );
54+
55+ CacheOptParser::CacheOptParser () : OptionsParser(" cache" , " Storage plugin implemented as a hash table" ),
56+ m_cache_size (1 << DEFAULT_FLOW_CACHE_SIZE), m_line_size(1 << DEFAULT_FLOW_LINE_SIZE),
57+ m_active(DEFAULT_ACTIVE_TIMEOUT), m_inactive(DEFAULT_INACTIVE_TIMEOUT), m_split_biflow(false ),
58+ m_enable_fragmentation_cache(true ), m_frag_cache_size(10007 ), // Prime for better distribution in hash table
59+ m_frag_cache_timeout(3 )
60+ {
61+ register_option (" s" , " size" , " EXPONENT" , " Cache size exponent to the power of two" ,
62+ [this ](const char *arg){try {unsigned exp = str2num<decltype (exp)>(arg);
63+ if (exp < 4 || exp > 30 ) {
64+ throw PluginError (" Flow cache size must be between 4 and 30" );
65+ }
66+ m_cache_size = static_cast <uint32_t >(1 ) << exp;
67+ } catch (std::invalid_argument &e) {return false ;} return true ;},
68+ OptionFlags::RequiredArgument);
69+ register_option (" l" , " line" , " EXPONENT" , " Cache line size exponent to the power of two" ,
70+ [this ](const char *arg){try {m_line_size = static_cast <uint32_t >(1 ) << str2num<decltype (m_line_size)>(arg);
71+ if (m_line_size < 1 ) {
72+ throw PluginError (" Flow cache line size must be at least 1" );
73+ }
74+ } catch (std::invalid_argument &e) {return false ;} return true ;},
75+ OptionFlags::RequiredArgument);
76+ register_option (" a" , " active" , " TIME" , " Active timeout in seconds" ,
77+ [this ](const char *arg){try {m_active = str2num<decltype (m_active)>(arg);} catch (std::invalid_argument &e) {return false ;} return true ;},
78+ OptionFlags::RequiredArgument);
79+ register_option (" i" , " inactive" , " TIME" , " Inactive timeout in seconds" ,
80+ [this ](const char *arg){try {m_inactive = str2num<decltype (m_inactive)>(arg);} catch (std::invalid_argument &e) {return false ;} return true ;},
81+ OptionFlags::RequiredArgument);
82+ register_option (" S" , " split" , " " , " Split biflows into uniflows" ,
83+ [this ](const char *arg){ m_split_biflow = true ; return true ;}, OptionFlags::NoArgument);
84+ register_option (" fe" , " frag-enable" , " true|false" , " Enable/disable fragmentation cache. Enabled (true) by default." ,
85+ [this ](const char *arg){
86+ if (strcmp (arg, " true" ) == 0 ) {
87+ m_enable_fragmentation_cache = true ;
88+ } else if (strcmp (arg, " false" ) == 0 ) {
89+ m_enable_fragmentation_cache = false ;
90+ } else {
91+ return false ;
92+ }
93+ return true ;
94+ }, OptionFlags::RequiredArgument);
95+ register_option (" fs" , " frag-size" , " size" , " Size of fragmentation cache, must be at least 1. Default value is 10007." , [this ](const char *arg) {
96+ try {
97+ m_frag_cache_size = str2num<decltype (m_frag_cache_size)>(arg);
98+ } catch (std::invalid_argument &e) {
99+ return false ;
100+ }
101+ return m_frag_cache_size > 0 ;
102+ });
103+ register_option (" ft" , " frag-timeout" , " TIME" , " Timeout of fragments in fragmentation cache in seconds. Default value is 3." , [this ](const char *arg) {
104+ try {
105+ m_frag_cache_timeout = str2num<decltype (m_frag_cache_timeout)>(arg);
106+ } catch (std::invalid_argument &e) {
107+ return false ;
108+ }
109+ return true ;
110+ });
111+ }
112+
113+
114+ } // ipxp
0 commit comments