size_t get_max_size()
{
- std::lock_guard<std::mutex> cache_lock(cache_mutex);
return max_size;
}
static constexpr size_t mem_chunk = sizeof(Data) + sizeof(Value);
- size_t max_size; // Once max_size elements are in the cache, start to
- // remove the least-recently-used elements.
+ std::atomic<size_t> max_size; // Once max_size elements are in the cache, start to
+ // remove the least-recently-used elements.
std::atomic<size_t> current_size;// Number of entries currently in the cache.
{
if ( snort::SnortConfig::log_verbose() )
{
- std::lock_guard<std::mutex> cache_lock(cache_mutex);
-
snort::LogLabel("host_cache");
- snort::LogMessage(" memcap: %zu bytes\n", max_size);
+ snort::LogMessage(" memcap: %zu bytes\n", max_size.load());
}
}
if ( current_size > new_size )
return true;
- std::lock_guard<std::mutex> cache_lock(cache_mutex);
max_size = new_size;
return false;
}
if ( !list.empty() )
{
- // A data race when reload changes max_size while other threads read this may
- // delay pruning by one round. Yet, we are avoiding mutex for better performance.
- max_size = current_size;
+ max_size.store(current_size);
if ( max_size > new_size )
{
LruListIter list_iter = --list.end();
return false;
}
-const uint8_t* HostTracker::get_last_seen_mac()
+const uint8_t* HostTracker::get_last_seen_mac(uint8_t* mac_addr)
{
lock_guard<mutex> lck(host_tracker_lock);
const HostMac_t* max_hm = nullptr;
max_hm = &hm;
if ( max_hm )
- return max_hm->mac;
+ {
+ memcpy(mac_addr, max_hm->mac, MAC_SIZE);
+ return mac_addr;
+ }
return zero_mac;
}
return false;
}
-HostMac* HostTracker::get_max_ttl_hostmac()
+bool HostTracker::reset_hops_if_primary()
{
lock_guard<mutex> lck(host_tracker_lock);
- HostMac_t* max_ttl_hm = nullptr;
- uint8_t max_ttl = 0;
-
for ( auto& hm : macs )
- {
if ( hm.primary and hm.visibility )
- return static_cast<HostMac*> (&hm);
-
- if ( hm.ttl > max_ttl and hm.visibility )
{
- max_ttl = hm.ttl;
- max_ttl_hm = &hm;
+ if ( !hops )
+ return false;
+ hops = 0;
+ return true;
}
- }
- return static_cast<HostMac*>(max_ttl_hm);
+ return false;
}
void HostTracker::update_vlan(uint16_t vth_pri_cfi_vlan, uint16_t vth_proto)
{
+ lock_guard<mutex> lck(host_tracker_lock);
vlan_tag_present = true;
vlan_tag.vth_pri_cfi_vlan = vth_pri_cfi_vlan;
vlan_tag.vth_proto = vth_proto;
bool HostTracker::has_vlan()
{
+ lock_guard<mutex> lck(host_tracker_lock);
return vlan_tag_present;
}
+bool HostTracker::has_same_vlan(uint16_t pvlan)
+{
+ lock_guard<mutex> lck(host_tracker_lock);
+ return vlan_tag_present and ( vlan_tag.vth_pri_cfi_vlan == pvlan );
+}
+
uint16_t HostTracker::get_vlan()
{
+ lock_guard<mutex> lck(host_tracker_lock);
return vlan_tag.vth_pri_cfi_vlan;
}
void HostTracker::get_vlan_details(uint8_t& cfi, uint8_t& priority, uint16_t& vid)
{
+ lock_guard<mutex> lck(host_tracker_lock);
cfi = vlan_tag.cfi();
priority = vlan_tag.priority();
vid = vlan_tag.vid();
bool add_payload(HostApplication&, Port, IpProtocol, const AppId payload,
const AppId service, size_t max_payloads);
- // Returns the hostmac pointer with the highest TTL
- HostMac* get_max_ttl_hostmac();
+ // Returns true after resetting hops if there is a primary mac
+ bool reset_hops_if_primary();
// Returns true and copy of the matching HostMac, false if no match...
bool get_hostmac(const uint8_t* mac, HostMac& hm);
- const uint8_t* get_last_seen_mac();
+ const uint8_t* get_last_seen_mac(uint8_t*);
void update_vlan(uint16_t vth_pri_cfi_vlan, uint16_t vth_proto);
bool has_vlan();
+ bool has_same_vlan(uint16_t);
uint16_t get_vlan();
void get_vlan_details(uint8_t& cfi, uint8_t& priority, uint16_t& vid);
using namespace snort;
+static THREAD_LOCAL uint8_t mac_addr[MAC_SIZE];
+
RnaTracker RnaAppDiscovery::get_server_rna_tracker(const Packet* p, RNAFlow* rna_flow)
{
return rna_flow->get_server(p->flow->server_ip);
{
if ( proto == IpProtocol::TCP )
logger.log(RNA_EVENT_NEW, NEW_TCP_SERVICE, p, &htp,
- (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(), &ha);
+ (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(mac_addr), &ha);
else
logger.log(RNA_EVENT_NEW, NEW_UDP_SERVICE, p, &htp,
- (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(), &ha);
+ (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(mac_addr), &ha);
ha.hits = 0; // hit count is reset after logs are written
htp->update_service(ha);
if ( proto == IpProtocol::TCP )
logger.log(RNA_EVENT_CHANGE, CHANGE_TCP_SERVICE_INFO, p, &srt,
(const struct in6_addr*) p->flow->server_ip.get_ip6_ptr(),
- srt->get_last_seen_mac(), &local_ha);
+ srt->get_last_seen_mac(mac_addr), &local_ha);
else
logger.log(RNA_EVENT_CHANGE, CHANGE_UDP_SERVICE_INFO, p, &srt,
(const struct in6_addr*) p->flow->server_ip.get_ip6_ptr(),
- srt->get_last_seen_mac(), &local_ha);
+ srt->get_last_seen_mac(mac_addr), &local_ha);
}
}
if ( new_client_payload )
logger.log(RNA_EVENT_CHANGE, CHANGE_CLIENT_APP_UPDATE, p, &crt,
(const struct in6_addr*) p->flow->client_ip.get_ip6_ptr(),
- crt->get_last_seen_mac(), &hc);
+ crt->get_last_seen_mac(mac_addr), &hc);
}
void RnaAppDiscovery::update_service_info(const Packet* p, DiscoveryFilter& filter,
if ( proto == IpProtocol::TCP )
logger.log(RNA_EVENT_CHANGE, CHANGE_TCP_SERVICE_INFO, p, &htp,
- (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(), &ha);
+ (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(mac_addr), &ha);
else
logger.log(RNA_EVENT_CHANGE, CHANGE_UDP_SERVICE_INFO, p, &htp,
- (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(), &ha);
+ (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(mac_addr), &ha);
ha.hits = 0;
htp->update_service(ha);
HostApplication ha(p->flow->server_port, proto, service, false);
ha.last_seen = (uint32_t) packet_time();
logger.log(RNA_EVENT_CHANGE, CHANGE_BANNER_UPDATE, p, &rt,
- (const struct in6_addr*) p->flow->server_ip.get_ip6_ptr(), rt->get_last_seen_mac(), &ha);
+ (const struct in6_addr*) p->flow->server_ip.get_ip6_ptr(),
+ rt->get_last_seen_mac(mac_addr), &ha);
}
void RnaAppDiscovery::discover_client(const Packet* p, DiscoveryFilter& filter, RNAFlow* rna_flow,
RnaTracker crt = get_client_rna_tracker(p, rna_flow);
if ( !crt or !crt->is_visible() )
return;
- mac = crt->get_last_seen_mac();
+ mac = crt->get_last_seen_mac(mac_addr);
}
if (conf and conf->max_host_client_apps and
device_info, MAX_USER_AGENT_DEVICES) )
{
logger.log(RNA_EVENT_NEW, NEW_OS, p, &rt,
- (const struct in6_addr*)p->flow->client_ip.get_ip6_ptr(), rt->get_last_seen_mac(),
- (FpFingerprint*)uafp, packet_time(), device_info, jail_broken);
+ (const struct in6_addr*)p->flow->client_ip.get_ip6_ptr(),
+ rt->get_last_seen_mac(mac_addr), (FpFingerprint*)uafp, packet_time(),
+ device_info, jail_broken);
}
}
return vlan_tag_present;
}
+bool HostTrackerMac::has_same_vlan(uint16_t pvlan)
+{
+ lock_guard<mutex> lck(host_tracker_mac_lock);
+ return vlan_tag_present and ( vlan_tag.vth_pri_cfi_vlan == pvlan );
+}
+
uint16_t HostTrackerMac::get_vlan()
{
lock_guard<mutex> lck(host_tracker_mac_lock);
void update_last_seen(uint32_t p_last_seen);
void update_vlan(uint16_t vth_pri_cfi_vlan, uint16_t vth_proto);
bool has_vlan();
+ bool has_same_vlan(uint16_t);
void get_vlan_details(uint8_t& cfi, uint8_t& priority, uint16_t& vid);
std::vector<uint16_t, HostCacheAllocMac<uint16_t>> get_network_protos()
logger.log(RNA_EVENT_CHANGE, CHANGE_MAC_INFO, p, &ht, src_ip_ptr, src_mac,
ht->get_hostmac(src_mac, hm) ? &hm : nullptr, packet_time());
- HostMac* hm_max_ttl = ht->get_max_ttl_hostmac();
- if (hm_max_ttl and hm_max_ttl->primary and ht->get_hops())
- {
- ht->update_hops(0);
+ if ( ht->reset_hops_if_primary() )
logger.log(RNA_EVENT_CHANGE, CHANGE_HOPS, p, &ht, src_ip_ptr, src_mac, packet_time());
- }
}
if ( p->is_tcp() and ht->get_host_type() == HOST_TYPE_HOST )
if ( !vh )
return;
- if ( isnew or !hm.has_vlan() or (hm.get_vlan() != vh->vth_pri_cfi_vlan) )
+ if ( isnew or !hm.has_same_vlan(vh->vth_pri_cfi_vlan) )
{
if ( !isnew )
update_vlan(p, hm);
if ( !vh )
return;
- if ( isnew or !rt->get()->has_vlan() or (rt->get()->get_vlan() != vh->vth_pri_cfi_vlan) )
+ if ( isnew or !rt->get()->has_same_vlan(vh->vth_pri_cfi_vlan) )
{
rt->get()->update_vlan(vh->vth_pri_cfi_vlan, vh->vth_proto);
logger.log(RNA_EVENT_CHANGE, CHANGE_VLAN_TAG, p, rt,
while ( data_len >= 2 )
{
- uint8_t opt_type, opt_len;
-
- opt_type = *data;
- opt_len = *(data + 1);
+ uint8_t opt_type = *data;
if ( opt_type == ICMPV6_OPTION_TARGET_LINKLAYER_ADDRESS )
neighbor_src_mac = data + 2;
+ uint8_t opt_len = *(data + 1);
+ if ( opt_len == 0 )
+ break;
data += opt_len * 8;
data_len -= opt_len * 8;
}
while ( data_len >= 2 )
{
- uint8_t opt_type, opt_len;
-
- opt_type = *data;
- opt_len = *(data + 1);
+ uint8_t opt_type = *data;
if ( opt_type == ICMPV6_OPTION_SOURCE_LINKLAYER_ADDRESS )
neighbor_src_mac = data + 2;
+ uint8_t opt_len = *(data + 1);
+ if ( opt_len == 0 )
+ break;
data += opt_len * 8;
data_len -= opt_len * 8;
}
std::vector<std::string>::const_iterator Trough::pcap_queue_iter;
unsigned Trough::pcap_loop_count = 0;
-unsigned Trough::file_count = 0;
+std::atomic<unsigned> Trough::file_count{0};
bool Trough::add_pcaps_dir(const std::string& dirname, const std::string& filter)
{
#ifndef TROUGH_H
#define TROUGH_H
+#include <atomic>
#include <string>
#include <vector>
static std::string pcap_filter;
static unsigned pcap_loop_count;
- static unsigned file_count;
+ static std::atomic<unsigned> file_count;
};
#endif