From 1e4964de7760ba83c9557b00fd8563e61e364d18 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 11 Dec 2017 15:29:28 -0600 Subject: [PATCH] Preallocate all possible PortVals. The performance benefit is small (maybe ~1% at most), however, it's a trivial change without downsides. --- src/CompHash.cc | 2 +- src/Conn.cc | 4 +- src/Event.cc | 2 +- src/IP.cc | 8 ++-- src/PersistenceSerializer.cc | 2 +- src/RemoteSerializer.cc | 2 +- src/TunnelEncapsulation.cc | 4 +- src/Val.cc | 47 +++++++++++++++++++ src/Val.h | 24 ++++++++-- src/analyzer/Manager.cc | 8 ++-- .../protocol/bittorrent/BitTorrentTracker.cc | 2 +- .../bittorrent/bittorrent-analyzer.pac | 2 +- src/analyzer/protocol/ftp/functions.bif | 6 +-- src/analyzer/protocol/icmp/ICMP.cc | 8 ++-- src/analyzer/protocol/ident/Ident.cc | 12 ++--- src/analyzer/protocol/rpc/Portmap.cc | 6 +-- .../protocol/socks/socks-analyzer.pac | 8 ++-- src/analyzer/protocol/tcp/TCP_Reassembler.cc | 7 +-- src/analyzer/protocol/teredo/Teredo.cc | 2 +- src/analyzer/protocol/udp/UDP.cc | 8 ++-- src/bro.bif | 14 +++--- src/broker/Data.cc | 2 +- src/broker/Manager.cc | 6 +-- src/broker/data.bif | 2 +- src/file_analysis/File.cc | 4 +- .../analyzer/unified2/unified2-analyzer.pac | 2 +- src/input/Manager.cc | 2 +- src/main.cc | 3 ++ src/scan.l | 8 ++-- 29 files changed, 139 insertions(+), 68 deletions(-) diff --git a/src/CompHash.cc b/src/CompHash.cc index 2e28bff78e..f120c3618b 100644 --- a/src/CompHash.cc +++ b/src/CompHash.cc @@ -703,7 +703,7 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0, break; case TYPE_PORT: - pval = new PortVal(*kp); + pval = port_mgr->Get(*kp); break; default: diff --git a/src/Conn.cc b/src/Conn.cc index 2034a57786..1edecde0b9 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -364,9 +364,9 @@ RecordVal* Connection::BuildConnVal() RecordVal* id_val = new RecordVal(conn_id); id_val->Assign(0, new AddrVal(orig_addr)); - id_val->Assign(1, new PortVal(ntohs(orig_port), prot_type)); + id_val->Assign(1, port_mgr->Get(ntohs(orig_port), prot_type)); id_val->Assign(2, new AddrVal(resp_addr)); - id_val->Assign(3, new PortVal(ntohs(resp_port), prot_type)); + id_val->Assign(3, port_mgr->Get(ntohs(resp_port), prot_type)); RecordVal *orig_endp = new RecordVal(endpoint); orig_endp->Assign(0, new Val(0, TYPE_COUNT)); diff --git a/src/Event.cc b/src/Event.cc index 6371a69248..7b1c88ea64 100644 --- a/src/Event.cc +++ b/src/Event.cc @@ -166,7 +166,7 @@ RecordVal* EventMgr::GetLocalPeerVal() src_val = new RecordVal(peer); src_val->Assign(0, new Val(0, TYPE_COUNT)); src_val->Assign(1, new AddrVal("127.0.0.1")); - src_val->Assign(2, new PortVal(0)); + src_val->Assign(2, port_mgr->Get(0)); src_val->Assign(3, new Val(true, TYPE_BOOL)); Ref(peer_description); diff --git a/src/IP.cc b/src/IP.cc index ebe778e3d7..79e1cf4fba 100644 --- a/src/IP.cc +++ b/src/IP.cc @@ -370,8 +370,8 @@ RecordVal* IP_Hdr::BuildPktHdrVal(RecordVal* pkt_hdr, int sindex) const int tcp_hdr_len = tp->th_off * 4; int data_len = PayloadLen() - tcp_hdr_len; - tcp_hdr->Assign(0, new PortVal(ntohs(tp->th_sport), TRANSPORT_TCP)); - tcp_hdr->Assign(1, new PortVal(ntohs(tp->th_dport), TRANSPORT_TCP)); + tcp_hdr->Assign(0, port_mgr->Get(ntohs(tp->th_sport), TRANSPORT_TCP)); + tcp_hdr->Assign(1, port_mgr->Get(ntohs(tp->th_dport), TRANSPORT_TCP)); tcp_hdr->Assign(2, new Val(uint32(ntohl(tp->th_seq)), TYPE_COUNT)); tcp_hdr->Assign(3, new Val(uint32(ntohl(tp->th_ack)), TYPE_COUNT)); tcp_hdr->Assign(4, new Val(tcp_hdr_len, TYPE_COUNT)); @@ -388,8 +388,8 @@ RecordVal* IP_Hdr::BuildPktHdrVal(RecordVal* pkt_hdr, int sindex) const const struct udphdr* up = (const struct udphdr*) data; RecordVal* udp_hdr = new RecordVal(udp_hdr_type); - udp_hdr->Assign(0, new PortVal(ntohs(up->uh_sport), TRANSPORT_UDP)); - udp_hdr->Assign(1, new PortVal(ntohs(up->uh_dport), TRANSPORT_UDP)); + udp_hdr->Assign(0, port_mgr->Get(ntohs(up->uh_sport), TRANSPORT_UDP)); + udp_hdr->Assign(1, port_mgr->Get(ntohs(up->uh_dport), TRANSPORT_UDP)); udp_hdr->Assign(2, new Val(ntohs(up->uh_ulen), TYPE_COUNT)); pkt_hdr->Assign(sindex + 3, udp_hdr); diff --git a/src/PersistenceSerializer.cc b/src/PersistenceSerializer.cc index 9400b2d0ca..52778ed10c 100644 --- a/src/PersistenceSerializer.cc +++ b/src/PersistenceSerializer.cc @@ -191,7 +191,7 @@ void PersistenceSerializer::RaiseFinishedSendState() { val_list* vl = new val_list; vl->append(new AddrVal(htonl(remote_host))); - vl->append(new PortVal(remote_port)); + vl->append(port_mgr->Get(remote_port)); mgr.QueueEvent(finished_send_state, vl); reporter->Log("Serialization done."); diff --git a/src/RemoteSerializer.cc b/src/RemoteSerializer.cc index 7d8899d8b9..78080e31f5 100644 --- a/src/RemoteSerializer.cc +++ b/src/RemoteSerializer.cc @@ -1809,7 +1809,7 @@ RecordVal* RemoteSerializer::MakePeerVal(Peer* peer) v->Assign(0, new Val(uint32(peer->id), TYPE_COUNT)); // Sic! Network order for AddrVal, host order for PortVal. v->Assign(1, new AddrVal(peer->ip)); - v->Assign(2, new PortVal(peer->port, TRANSPORT_TCP)); + v->Assign(2, port_mgr->Get(peer->port, TRANSPORT_TCP)); v->Assign(3, new Val(false, TYPE_BOOL)); v->Assign(4, new StringVal("")); // set when received v->Assign(5, peer->peer_class.size() ? diff --git a/src/TunnelEncapsulation.cc b/src/TunnelEncapsulation.cc index cb4b1eaabe..556de9382a 100644 --- a/src/TunnelEncapsulation.cc +++ b/src/TunnelEncapsulation.cc @@ -22,9 +22,9 @@ RecordVal* EncapsulatingConn::GetRecordVal() const RecordVal* id_val = new RecordVal(conn_id); id_val->Assign(0, new AddrVal(src_addr)); - id_val->Assign(1, new PortVal(ntohs(src_port), proto)); + id_val->Assign(1, port_mgr->Get(ntohs(src_port), proto)); id_val->Assign(2, new AddrVal(dst_addr)); - id_val->Assign(3, new PortVal(ntohs(dst_port), proto)); + id_val->Assign(3, port_mgr->Get(ntohs(dst_port), proto)); rv->Assign(0, id_val); rv->Assign(1, new EnumVal(type, BifType::Enum::Tunnel::Type)); diff --git a/src/Val.cc b/src/Val.cc index ca70e1f5df..abae677754 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -760,6 +760,53 @@ bool IntervalVal::DoUnserialize(UnserialInfo* info) return true; } +PortManager::PortManager() + { + for ( auto i = 0u; i < ports.size(); ++i ) + { + auto& arr = ports[i]; + auto port_type = (TransportProto)i; + + for ( auto j = 0u; j < arr.size(); ++j ) + arr[j] = new PortVal(j, port_type); + } + } + +PortManager::~PortManager() + { + for ( auto& arr : ports ) + for ( auto& pv : arr ) + Unref(pv); + } + +PortVal* PortManager::Get(uint32 port_num) const + { + auto mask = port_num & PORT_SPACE_MASK; + port_num &= ~PORT_SPACE_MASK; + + if ( mask == TCP_PORT_MASK ) + return Get(port_num, TRANSPORT_TCP); + else if ( mask == UDP_PORT_MASK ) + return Get(port_num, TRANSPORT_UDP); + else if ( mask == ICMP_PORT_MASK ) + return Get(port_num, TRANSPORT_ICMP); + else + return Get(port_num, TRANSPORT_UNKNOWN); + } + +PortVal* PortManager::Get(uint32 port_num, TransportProto port_type) const + { + if ( port_num >= 65536 ) + { + reporter->Warning("bad port number %d", port_num); + port_num = 0; + } + + auto rval = ports[port_type][port_num]; + ::Ref(rval); + return rval; + } + PortVal::PortVal(uint32 p, TransportProto port_type) : Val(TYPE_PORT) { // Note, for ICMP one-way connections: diff --git a/src/Val.h b/src/Val.h index 160eeafe64..d0538db8ee 100644 --- a/src/Val.h +++ b/src/Val.h @@ -7,6 +7,7 @@ #include #include +#include #include "net_util.h" #include "Type.h" @@ -503,12 +504,22 @@ protected: #define UDP_PORT_MASK 0x20000 #define ICMP_PORT_MASK 0x30000 +class PortManager { +public: + PortManager(); + ~PortManager(); + + // Port number given in host order. + PortVal* Get(uint32 port_num) const; + PortVal* Get(uint32 port_num, TransportProto port_type) const; + + std::array, NUM_PORT_SPACES> ports; +}; + +extern PortManager* port_mgr; + class PortVal : public Val { public: - // Constructors - both take the port number in host order. - PortVal(uint32 p, TransportProto port_type); - PortVal(uint32 p); // used for already-massaged port value. - Val* SizeVal() const override { return new Val(val.uint_val, TYPE_INT); } // Returns the port number in host order (not including the mask). @@ -533,7 +544,12 @@ public: protected: friend class Val; + friend class PortManager; PortVal() {} + // Constructors - both take the port number in host order. + PortVal(uint32 p, TransportProto port_type); + PortVal(uint32 p); // used for already-massaged port value. + void ValDescribe(ODesc* d) const override; diff --git a/src/analyzer/Manager.cc b/src/analyzer/Manager.cc index 9858001c6f..4b5441f395 100644 --- a/src/analyzer/Manager.cc +++ b/src/analyzer/Manager.cc @@ -434,14 +434,16 @@ bool Manager::BuildInitialAnalyzerTree(Connection* conn) if ( tcp_contents && ! reass ) { - PortVal dport(ntohs(conn->RespPort()), TRANSPORT_TCP); + auto dport = port_mgr->Get(ntohs(conn->RespPort()), TRANSPORT_TCP); Val* result; if ( ! reass ) - reass = tcp_content_delivery_ports_orig->Lookup(&dport); + reass = tcp_content_delivery_ports_orig->Lookup(dport); if ( ! reass ) - reass = tcp_content_delivery_ports_resp->Lookup(&dport); + reass = tcp_content_delivery_ports_resp->Lookup(dport); + + Unref(dport); } if ( reass ) diff --git a/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc b/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc index 43ee6a2b21..452fb0fe6c 100644 --- a/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc +++ b/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc @@ -482,7 +482,7 @@ void BitTorrentTracker_Analyzer::ResponseBenc(int name_len, char* name, RecordVal* peer = new RecordVal(bittorrent_peer); peer->Assign(0, new AddrVal(ad)); - peer->Assign(1, new PortVal(pt, TRANSPORT_TCP)); + peer->Assign(1, port_mgr->Get(pt, TRANSPORT_TCP)); res_val_peers->Assign(peer, 0); Unref(peer); diff --git a/src/analyzer/protocol/bittorrent/bittorrent-analyzer.pac b/src/analyzer/protocol/bittorrent/bittorrent-analyzer.pac index 3bc6d90230..6040577d39 100644 --- a/src/analyzer/protocol/bittorrent/bittorrent-analyzer.pac +++ b/src/analyzer/protocol/bittorrent/bittorrent-analyzer.pac @@ -222,7 +222,7 @@ flow BitTorrent_Flow(is_orig: bool) { connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), is_orig(), - new PortVal(listen_port, TRANSPORT_TCP)); + port_mgr->Get(listen_port, TRANSPORT_TCP)); } return true; diff --git a/src/analyzer/protocol/ftp/functions.bif b/src/analyzer/protocol/ftp/functions.bif index b57b24df20..9508061102 100644 --- a/src/analyzer/protocol/ftp/functions.bif +++ b/src/analyzer/protocol/ftp/functions.bif @@ -33,13 +33,13 @@ static Val* parse_port(const char* line) } r->Assign(0, new AddrVal(htonl(addr))); - r->Assign(1, new PortVal(port, TRANSPORT_TCP)); + r->Assign(1, port_mgr->Get(port, TRANSPORT_TCP)); r->Assign(2, new Val(good, TYPE_BOOL)); } else { r->Assign(0, new AddrVal(uint32(0))); - r->Assign(1, new PortVal(0, TRANSPORT_TCP)); + r->Assign(1, port_mgr->Get(0, TRANSPORT_TCP)); r->Assign(2, new Val(0, TYPE_BOOL)); } @@ -109,7 +109,7 @@ static Val* parse_eftp(const char* line) } r->Assign(0, new AddrVal(addr)); - r->Assign(1, new PortVal(port, TRANSPORT_TCP)); + r->Assign(1, port_mgr->Get(port, TRANSPORT_TCP)); r->Assign(2, new Val(good, TYPE_BOOL)); return r; diff --git a/src/analyzer/protocol/icmp/ICMP.cc b/src/analyzer/protocol/icmp/ICMP.cc index 6a42e064d7..2dedca5ae1 100644 --- a/src/analyzer/protocol/icmp/ICMP.cc +++ b/src/analyzer/protocol/icmp/ICMP.cc @@ -352,9 +352,9 @@ RecordVal* ICMP_Analyzer::ExtractICMP4Context(int len, const u_char*& data) RecordVal* id_val = new RecordVal(conn_id); id_val->Assign(0, new AddrVal(src_addr)); - id_val->Assign(1, new PortVal(src_port, proto)); + id_val->Assign(1, port_mgr->Get(src_port, proto)); id_val->Assign(2, new AddrVal(dst_addr)); - id_val->Assign(3, new PortVal(dst_port, proto)); + id_val->Assign(3, port_mgr->Get(dst_port, proto)); iprec->Assign(0, id_val); iprec->Assign(1, new Val(ip_len, TYPE_COUNT)); @@ -411,9 +411,9 @@ RecordVal* ICMP_Analyzer::ExtractICMP6Context(int len, const u_char*& data) RecordVal* id_val = new RecordVal(conn_id); id_val->Assign(0, new AddrVal(src_addr)); - id_val->Assign(1, new PortVal(src_port, proto)); + id_val->Assign(1, port_mgr->Get(src_port, proto)); id_val->Assign(2, new AddrVal(dst_addr)); - id_val->Assign(3, new PortVal(dst_port, proto)); + id_val->Assign(3, port_mgr->Get(dst_port, proto)); iprec->Assign(0, id_val); iprec->Assign(1, new Val(ip_len, TYPE_COUNT)); diff --git a/src/analyzer/protocol/ident/Ident.cc b/src/analyzer/protocol/ident/Ident.cc index 9601be7562..27eafb5426 100644 --- a/src/analyzer/protocol/ident/Ident.cc +++ b/src/analyzer/protocol/ident/Ident.cc @@ -82,8 +82,8 @@ void Ident_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig) val_list* vl = new val_list; vl->append(BuildConnVal()); - vl->append(new PortVal(local_port, TRANSPORT_TCP)); - vl->append(new PortVal(remote_port, TRANSPORT_TCP)); + vl->append(port_mgr->Get(local_port, TRANSPORT_TCP)); + vl->append(port_mgr->Get(remote_port, TRANSPORT_TCP)); ConnectionEvent(ident_request, vl); @@ -143,8 +143,8 @@ void Ident_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig) { val_list* vl = new val_list; vl->append(BuildConnVal()); - vl->append(new PortVal(local_port, TRANSPORT_TCP)); - vl->append(new PortVal(remote_port, TRANSPORT_TCP)); + vl->append(port_mgr->Get(local_port, TRANSPORT_TCP)); + vl->append(port_mgr->Get(remote_port, TRANSPORT_TCP)); vl->append(new StringVal(end_of_line - line, line)); ConnectionEvent(ident_error, vl); @@ -177,8 +177,8 @@ void Ident_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig) val_list* vl = new val_list; vl->append(BuildConnVal()); - vl->append(new PortVal(local_port, TRANSPORT_TCP)); - vl->append(new PortVal(remote_port, TRANSPORT_TCP)); + vl->append(port_mgr->Get(local_port, TRANSPORT_TCP)); + vl->append(port_mgr->Get(remote_port, TRANSPORT_TCP)); vl->append(new StringVal(end_of_line - line, line)); vl->append(new StringVal(sys_type_s)); diff --git a/src/analyzer/protocol/rpc/Portmap.cc b/src/analyzer/protocol/rpc/Portmap.cc index 5d7c980879..9f52394ac4 100644 --- a/src/analyzer/protocol/rpc/Portmap.cc +++ b/src/analyzer/protocol/rpc/Portmap.cc @@ -126,7 +126,7 @@ int PortmapperInterp::RPC_BuildReply(RPC_CallInfo* c, BifEnum::rpc_status status RecordVal* rv = c->RequestVal()->AsRecordVal(); Val* is_tcp = rv->Lookup(2); - reply = new PortVal(CheckPort(port), + reply = port_mgr->Get(CheckPort(port), is_tcp->IsOne() ? TRANSPORT_TCP : TRANSPORT_UDP); event = pm_request_getport; @@ -178,7 +178,7 @@ int PortmapperInterp::RPC_BuildReply(RPC_CallInfo* c, BifEnum::rpc_status status if ( ! opaque_reply ) return 0; - reply = new PortVal(CheckPort(port), TRANSPORT_UDP); + reply = port_mgr->Get(CheckPort(port), TRANSPORT_UDP); event = pm_request_callit; } else @@ -202,7 +202,7 @@ Val* PortmapperInterp::ExtractMapping(const u_char*& buf, int& len) int is_tcp = extract_XDR_uint32(buf, len) == IPPROTO_TCP; uint32 port = extract_XDR_uint32(buf, len); - mapping->Assign(2, new PortVal(CheckPort(port), + mapping->Assign(2, port_mgr->Get(CheckPort(port), is_tcp ? TRANSPORT_TCP : TRANSPORT_UDP)); if ( ! buf ) diff --git a/src/analyzer/protocol/socks/socks-analyzer.pac b/src/analyzer/protocol/socks/socks-analyzer.pac index b8c4165a54..0f13335785 100644 --- a/src/analyzer/protocol/socks/socks-analyzer.pac +++ b/src/analyzer/protocol/socks/socks-analyzer.pac @@ -32,7 +32,7 @@ refine connection SOCKS_Conn += { 4, ${request.command}, sa, - new PortVal(${request.port} | TCP_PORT_MASK), + port_mgr->Get(${request.port} | TCP_PORT_MASK), array_to_string(${request.user})); static_cast(bro_analyzer())->EndpointDone(true); @@ -50,7 +50,7 @@ refine connection SOCKS_Conn += { 4, ${reply.status}, sa, - new PortVal(${reply.port} | TCP_PORT_MASK)); + port_mgr->Get(${reply.port} | TCP_PORT_MASK)); bro_analyzer()->ProtocolConfirmation(); static_cast(bro_analyzer())->EndpointDone(false); @@ -102,7 +102,7 @@ refine connection SOCKS_Conn += { 5, ${request.command}, sa, - new PortVal(${request.port} | TCP_PORT_MASK), + port_mgr->Get(${request.port} | TCP_PORT_MASK), new StringVal("")); static_cast(bro_analyzer())->EndpointDone(true); @@ -141,7 +141,7 @@ refine connection SOCKS_Conn += { 5, ${reply.reply}, sa, - new PortVal(${reply.port} | TCP_PORT_MASK)); + port_mgr->Get(${reply.port} | TCP_PORT_MASK)); bro_analyzer()->ProtocolConfirmation(); static_cast(bro_analyzer())->EndpointDone(false); diff --git a/src/analyzer/protocol/tcp/TCP_Reassembler.cc b/src/analyzer/protocol/tcp/TCP_Reassembler.cc index b1d7dca012..bcbe20d499 100644 --- a/src/analyzer/protocol/tcp/TCP_Reassembler.cc +++ b/src/analyzer/protocol/tcp/TCP_Reassembler.cc @@ -38,18 +38,19 @@ TCP_Reassembler::TCP_Reassembler(analyzer::Analyzer* arg_dst_analyzer, if ( ::tcp_contents ) { - // Val dst_port_val(ntohs(Conn()->RespPort()), TYPE_PORT); - PortVal dst_port_val(ntohs(tcp_analyzer->Conn()->RespPort()), + auto dst_port_val = port_mgr->Get(ntohs(tcp_analyzer->Conn()->RespPort()), TRANSPORT_TCP); TableVal* ports = IsOrig() ? tcp_content_delivery_ports_orig : tcp_content_delivery_ports_resp; - Val* result = ports->Lookup(&dst_port_val); + Val* result = ports->Lookup(dst_port_val); if ( (IsOrig() && tcp_content_deliver_all_orig) || (! IsOrig() && tcp_content_deliver_all_resp) || (result && result->AsBool()) ) deliver_tcp_contents = 1; + + Unref(dst_port_val); } } diff --git a/src/analyzer/protocol/teredo/Teredo.cc b/src/analyzer/protocol/teredo/Teredo.cc index 663e61749d..3d7fb397fb 100644 --- a/src/analyzer/protocol/teredo/Teredo.cc +++ b/src/analyzer/protocol/teredo/Teredo.cc @@ -130,7 +130,7 @@ RecordVal* TeredoEncapsulation::BuildVal(const IP_Hdr* inner) const RecordVal* teredo_origin = new RecordVal(teredo_origin_type); uint16 port = ntohs(*((uint16*)(origin_indication + 2))) ^ 0xFFFF; uint32 addr = ntohl(*((uint32*)(origin_indication + 4))) ^ 0xFFFFFFFF; - teredo_origin->Assign(0, new PortVal(port, TRANSPORT_UDP)); + teredo_origin->Assign(0, port_mgr->Get(port, TRANSPORT_UDP)); teredo_origin->Assign(1, new AddrVal(htonl(addr))); teredo_hdr->Assign(1, teredo_origin); } diff --git a/src/analyzer/protocol/udp/UDP.cc b/src/analyzer/protocol/udp/UDP.cc index 3bd3736b2a..ca46b88339 100644 --- a/src/analyzer/protocol/udp/UDP.cc +++ b/src/analyzer/protocol/udp/UDP.cc @@ -97,14 +97,14 @@ void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, if ( udp_contents ) { - PortVal port_val(ntohs(up->uh_dport), TRANSPORT_UDP); + auto port_val = port_mgr->Get(ntohs(up->uh_dport), TRANSPORT_UDP); Val* result = 0; bool do_udp_contents = false; if ( is_orig ) { result = udp_content_delivery_ports_orig->Lookup( - &port_val); + port_val); if ( udp_content_deliver_all_orig || (result && result->AsBool()) ) do_udp_contents = true; @@ -112,7 +112,7 @@ void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, else { result = udp_content_delivery_ports_resp->Lookup( - &port_val); + port_val); if ( udp_content_deliver_all_resp || (result && result->AsBool()) ) do_udp_contents = true; @@ -126,6 +126,8 @@ void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, vl->append(new StringVal(len, (const char*) data)); ConnectionEvent(udp_contents, vl); } + + Unref(port_val); } if ( is_orig ) diff --git a/src/bro.bif b/src/bro.bif index 852f806230..b6922f9fab 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -2270,7 +2270,7 @@ function port_to_count%(p: port%): count ## .. bro:see:: port_to_count function count_to_port%(num: count, proto: transport_proto%): port %{ - return new PortVal(num, (TransportProto)proto->AsEnum()); + return port_mgr->Get(num, (TransportProto)proto->AsEnum()); %} ## Converts a :bro:type:`string` to an :bro:type:`addr`. @@ -2430,16 +2430,16 @@ function to_port%(s: string%): port { ++slash; if ( streq(slash, "tcp") ) - return new PortVal(port, TRANSPORT_TCP); + return port_mgr->Get(port, TRANSPORT_TCP); else if ( streq(slash, "udp") ) - return new PortVal(port, TRANSPORT_UDP); + return port_mgr->Get(port, TRANSPORT_UDP); else if ( streq(slash, "icmp") ) - return new PortVal(port, TRANSPORT_ICMP); + return port_mgr->Get(port, TRANSPORT_ICMP); } } builtin_error("wrong port format, must be /[0-9]{1,5}\\/(tcp|udp|icmp)/"); - return new PortVal(port, TRANSPORT_UNKNOWN); + return port_mgr->Get(port, TRANSPORT_UNKNOWN); %} ## Converts a string of bytes (in network byte order) to a :bro:type:`double`. @@ -3208,9 +3208,9 @@ function lookup_connection%(cid: conn_id%): connection RecordVal* id_val = new RecordVal(conn_id); id_val->Assign(0, new AddrVal((unsigned int) 0)); - id_val->Assign(1, new PortVal(ntohs(0), TRANSPORT_UDP)); + id_val->Assign(1, port_mgr->Get(ntohs(0), TRANSPORT_UDP)); id_val->Assign(2, new AddrVal((unsigned int) 0)); - id_val->Assign(3, new PortVal(ntohs(0), TRANSPORT_UDP)); + id_val->Assign(3, port_mgr->Get(ntohs(0), TRANSPORT_UDP)); c->Assign(0, id_val); RecordVal* orig_endp = new RecordVal(endpoint); diff --git a/src/broker/Data.cc b/src/broker/Data.cc index 6420144193..09b0da11e1 100644 --- a/src/broker/Data.cc +++ b/src/broker/Data.cc @@ -135,7 +135,7 @@ struct val_converter { result_type operator()(broker::port& a) { if ( type->Tag() == TYPE_PORT ) - return new PortVal(a.number(), bro_broker::to_bro_port_proto(a.type())); + return port_mgr->Get(a.number(), bro_broker::to_bro_port_proto(a.type())); return nullptr; } diff --git a/src/broker/Manager.cc b/src/broker/Manager.cc index eebcd2792f..d5acb27b5a 100644 --- a/src/broker/Manager.cc +++ b/src/broker/Manager.cc @@ -697,7 +697,7 @@ void bro_broker::Manager::Process() { val_list* vl = new val_list; vl->append(new StringVal(u.relation.remote_tuple().first)); - vl->append(new PortVal(u.relation.remote_tuple().second, + vl->append(port_mgr->Get(u.relation.remote_tuple().second, TRANSPORT_TCP)); vl->append(new StringVal(u.peer_name)); mgr.QueueEvent(Broker::outgoing_connection_established, vl); @@ -709,7 +709,7 @@ void bro_broker::Manager::Process() { val_list* vl = new val_list; vl->append(new StringVal(u.relation.remote_tuple().first)); - vl->append(new PortVal(u.relation.remote_tuple().second, + vl->append(port_mgr->Get(u.relation.remote_tuple().second, TRANSPORT_TCP)); mgr.QueueEvent(Broker::outgoing_connection_broken, vl); } @@ -720,7 +720,7 @@ void bro_broker::Manager::Process() { val_list* vl = new val_list; vl->append(new StringVal(u.relation.remote_tuple().first)); - vl->append(new PortVal(u.relation.remote_tuple().second, + vl->append(port_mgr->Get(u.relation.remote_tuple().second, TRANSPORT_TCP)); mgr.QueueEvent(Broker::outgoing_connection_incompatible, vl); } diff --git a/src/broker/data.bif b/src/broker/data.bif index d526d0a779..7f9c27f9a2 100644 --- a/src/broker/data.bif +++ b/src/broker/data.bif @@ -88,7 +88,7 @@ function Broker::__refine_to_port%(d: Broker::Data%): port %{ auto& a = bro_broker::require_data_type(d->AsRecordVal(), TYPE_PORT, frame); - return new PortVal(a.number(), bro_broker::to_bro_port_proto(a.type())); + return port_mgr->Get(a.number(), bro_broker::to_bro_port_proto(a.type())); %} function Broker::__refine_to_time%(d: Broker::Data%): time diff --git a/src/file_analysis/File.cc b/src/file_analysis/File.cc index 46624e23c0..711186335e 100644 --- a/src/file_analysis/File.cc +++ b/src/file_analysis/File.cc @@ -34,9 +34,9 @@ static RecordVal* get_conn_id_val(const Connection* conn) { RecordVal* v = new RecordVal(conn_id); v->Assign(0, new AddrVal(conn->OrigAddr())); - v->Assign(1, new PortVal(ntohs(conn->OrigPort()), conn->ConnTransport())); + v->Assign(1, port_mgr->Get(ntohs(conn->OrigPort()), conn->ConnTransport())); v->Assign(2, new AddrVal(conn->RespAddr())); - v->Assign(3, new PortVal(ntohs(conn->RespPort()), conn->ConnTransport())); + v->Assign(3, port_mgr->Get(ntohs(conn->RespPort()), conn->ConnTransport())); return v; } diff --git a/src/file_analysis/analyzer/unified2/unified2-analyzer.pac b/src/file_analysis/analyzer/unified2/unified2-analyzer.pac index 11072f140b..bedf54be5b 100644 --- a/src/file_analysis/analyzer/unified2/unified2-analyzer.pac +++ b/src/file_analysis/analyzer/unified2/unified2-analyzer.pac @@ -54,7 +54,7 @@ refine flow Flow += { case 17: proto = TRANSPORT_UDP; break; } - return new PortVal(n, proto); + return port_mgr->Get(n, proto); %} #function proc_record(rec: Record) : bool diff --git a/src/input/Manager.cc b/src/input/Manager.cc index d029e38092..9a7f1f052f 100644 --- a/src/input/Manager.cc +++ b/src/input/Manager.cc @@ -2287,7 +2287,7 @@ Val* Manager::ValueToVal(const Stream* i, const Value* val, BroType* request_typ } case TYPE_PORT: - return new PortVal(val->val.port_val.port, val->val.port_val.proto); + return port_mgr->Get(val->val.port_val.port, val->val.port_val.proto); case TYPE_ADDR: { diff --git a/src/main.cc b/src/main.cc index 0ca39e9e2d..a1ae750963 100644 --- a/src/main.cc +++ b/src/main.cc @@ -87,6 +87,7 @@ int perftools_profile = 0; DNS_Mgr* dns_mgr; TimerMgr* timer_mgr; +PortManager* port_mgr = 0; logging::Manager* log_mgr = 0; threading::Manager* thread_mgr = 0; input::Manager* input_mgr = 0; @@ -384,6 +385,7 @@ void terminate_bro() delete plugin_mgr; delete reporter; delete iosource_mgr; + delete port_mgr; reporter = 0; } @@ -711,6 +713,7 @@ int main(int argc, char** argv) bro_start_time = current_time(true); + port_mgr = new PortManager(); reporter = new Reporter(); thread_mgr = new threading::Manager(); plugin_mgr = new plugin::Manager(); diff --git a/src/scan.l b/src/scan.l index cdac72c1cd..46848f78fd 100644 --- a/src/scan.l +++ b/src/scan.l @@ -474,7 +474,7 @@ F RET_CONST(new Val(false, TYPE_BOOL)) reporter->Error("bad port number - %s", yytext); p = 0; } - RET_CONST(new PortVal(p, TRANSPORT_TCP)) + RET_CONST(port_mgr->Get(p, TRANSPORT_TCP)) } {D}"/udp" { uint32 p = atoi(yytext); @@ -483,7 +483,7 @@ F RET_CONST(new Val(false, TYPE_BOOL)) reporter->Error("bad port number - %s", yytext); p = 0; } - RET_CONST(new PortVal(p, TRANSPORT_UDP)) + RET_CONST(port_mgr->Get(p, TRANSPORT_UDP)) } {D}"/icmp" { uint32 p = atoi(yytext); @@ -492,7 +492,7 @@ F RET_CONST(new Val(false, TYPE_BOOL)) reporter->Error("bad port number - %s", yytext); p = 0; } - RET_CONST(new PortVal(p, TRANSPORT_ICMP)) + RET_CONST(port_mgr->Get(p, TRANSPORT_ICMP)) } {D}"/unknown" { uint32 p = atoi(yytext); @@ -501,7 +501,7 @@ F RET_CONST(new Val(false, TYPE_BOOL)) reporter->Error("bad port number - %s", yytext); p = 0; } - RET_CONST(new PortVal(p, TRANSPORT_UNKNOWN)) + RET_CONST(port_mgr->Get(p, TRANSPORT_UNKNOWN)) } {FLOAT}{OWS}day(s?) RET_CONST(new IntervalVal(atof(yytext),Days))