# How to count concurrent connections

**URL:** <https://community.zeek.org/t/how-to-count-concurrent-connections/1247>\
**Category:** Zeek\
**Created:** [October 11, 2007, 1:03pm UTC](https://community.zeek.org/t/how-to-count-concurrent-connections/1247 "2007-10-11T13:03:32Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Bernhard\_Ager](https://avatars.discourse-cdn.com/v4/letter/b/35a633/32.png) [@Bernhard\_Ager](https://community.zeek.org/u/Bernhard_Ager)\
**Post date:** [October 11, 2007, 1:03pm UTC](https://community.zeek.org/t/how-to-count-concurrent-connections/1247/1 "2007-10-11T13:03:32Z")

</div>

Hi,

I am currently trying to count concurrent connections. I'd like to use  
a script like this:

&nbsp;&nbsp;&nbsp;&nbsp;redef ignore\_checksums = T;  
&nbsp;&nbsp;&nbsp;&nbsp;redef capture\_filters += { ["tcp-setup"] = "tcp" };

&nbsp;&nbsp;&nbsp;&nbsp;global conncounter\_file = open\_log\_file ("conncounter");  
&nbsp;&nbsp;&nbsp;&nbsp;global total\_conn\_count = 0;  
&nbsp;&nbsp;&nbsp;&nbsp;global concurrent\_conn\_count = 0;  
&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;&nbsp;&nbsp;event connection\_established (c: connection) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++total\_conn\_count;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++concurrent\_conn\_count;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (total\_conn\_count % 1000 == 0) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print conncounter\_file, fmt ("%.06f total: %08d max concurrent: %d",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;network\_time(), total\_conn\_count, concurrent\_conn\_count);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;&nbsp;&nbsp;event connection\_state\_removed (c: connection) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--concurrent\_conn\_count;  
&nbsp;&nbsp;&nbsp;&nbsp;}

However, the numbers I get soon become negative resp. I get a runtime  
error - counter negative. A quick check showed me that  
connection\_state\_removed gets thrown up to four times per connection  
in only the first few minutes of my trace.

I then tried to replace connection\_state\_removed() with  
connection\_reset() and connection\_finished(). However I am not  
convinced this is enough because even after more then 90 minutes trace  
time concurrent\_conn\_count is still increasing significantly (~1300  
per minute on a 1 Gig uplink).

So my question now is: which events are thrown when exactly? Do I have  
to track the established connections in the scripting layer? Is there  
a way to just query for the size of the bro-internal connection  
tracker?

BTW: I am using a header trace. In my opinion this shouldn't make a  
difference, but maybe ...

Thanks for help!  
&nbsp;&nbsp;Bernhard

---

<div class="post-metadata">

**Author:** ![robin](https://yyz1.discourse-cdn.com/flex011/user_avatar/community.zeek.org/robin/32/599_2.png) [@robin](https://community.zeek.org/u/robin)\
**Post date:** [October 11, 2007, 5:45pm UTC](https://community.zeek.org/t/how-to-count-concurrent-connections/1247/2 "2007-10-11T17:45:53Z")

</div>

> So my question now is: which events are thrown when exactly?

The event you're looking for is new\_connection(). That one is raised  
for all connections for which Bro instantiates internal state, i.e.,  
it's the counterpart of connection\_state\_remove().

The other connection events are only raised for a subset of all  
connections. connection\_established() for those with a full 3w  
handshake, connection\_finished() for regular tear-downs,  
connection\_reset() for connection aborted with a reset, etc.

> Is there  
> a way to just query for the size of the bro-internal connection  
> tracker?

Actually there is: the built-in resource\_usage() returns a record  
which, among other stuff, contains the numbers of TCP, UDP, ICMP  
connections in memory. Caveat: I'm just realizing that this  
reporting doesn't take the connection-compressor into account, which  
means that by default the values will be too small for TCP  
connections. Turning off the compressor with  
use\_connection\_compressor=F will fix that for the cost of some  
performance decrease (both cpu and memory).

> BTW: I am using a header trace. In my opinion this shouldn't make a  
> difference, but maybe ...

No, it shouldn't.

Robin

---

<div class="post-metadata">

**Author:** ![Bernhard\_Ager](https://avatars.discourse-cdn.com/v4/letter/b/35a633/32.png) [@Bernhard\_Ager](https://community.zeek.org/u/Bernhard_Ager)\
**Post date:** [October 12, 2007, 3:34pm UTC](https://community.zeek.org/t/how-to-count-concurrent-connections/1247/3 "2007-10-12T15:34:02Z")

</div>

> The event you're looking for is new\_connection(). That one is raised  
> for all connections for which Bro instantiates internal state, i.e.,  
> it's the counterpart of connection\_state\_remove().

No, it is not 🙂 I only want fully established tcp connections. I  
tried out new\_connection() however, and it gives me about 8 times more  
connections than there are fully-established tcp-connections (450k vs.  
60k). By the way, I got my numbers now by using  
connection\_established() to detect new connections,  
connection\_state\_remove() for decreasing the counter and a set of  
conn\_id to ensure that a connection is removed only once. The price -  
of course - is the memory consumption of the extra table.

> Actually there is: the built-in resource\_usage() returns a record  
> which, among other stuff, contains the numbers of TCP, UDP, ICMP  
> connections in memory.

I tried out the built-in resource\_usage() as well, it gives pretty  
much the same results as the new\_connection() approach:

1184669769.879156 total: 00116000 concurrent: 63310 max\_TCP\_conns: 63311 num\_TCP\_conns: 63310  
1184669770.121984 total: 00117000 concurrent: 63796 max\_TCP\_conns: 63797 num\_TCP\_conns: 63796  
1184669770.398366 total: 00118000 concurrent: 64256 max\_TCP\_conns: 64256 num\_TCP\_conns: 64256

However, sometimes, odd things happen. Like here, where  
resource\_usage()$max\_TCP\_conns almost doubles for a short period of  
time (this is still in the startup phase):

1184669770.658614 total: 00119000 concurrent: 64683 max\_TCP\_conns: 64684 num\_TCP\_conns: 64683  
1184669770.969641 total: 00120000 concurrent: 65106 max\_TCP\_conns: 73977 num\_TCP\_conns: 65106  
1184669771.274491 total: 00121000 concurrent: 65511 max\_TCP\_conns: 83514 num\_TCP\_conns: 65511  
1184669771.570219 total: 00122000 concurrent: 65973 max\_TCP\_conns: 93163 num\_TCP\_conns: 65973  
1184669771.870853 total: 00123000 concurrent: 66452 max\_TCP\_conns: 102929 num\_TCP\_conns: 66452  
1184669772.109635 total: 00124000 concurrent: 66873 max\_TCP\_conns: 112785 num\_TCP\_conns: 66873  
1184669772.382840 total: 00125000 concurrent: 67299 max\_TCP\_conns: 122752 num\_TCP\_conns: 67299  
1184669772.672518 total: 00126000 concurrent: 67767 max\_TCP\_conns: 67768 num\_TCP\_conns: 67767

After looking into the code this seems to happen exactly when the  
underlying PDict object does a table resize.

Bye,  
&nbsp;&nbsp;Bernhard

---

<div class="post-metadata">

**Author:** ![robin](https://yyz1.discourse-cdn.com/flex011/user_avatar/community.zeek.org/robin/32/599_2.png) [@robin](https://community.zeek.org/u/robin)\
**Post date:** [October 14, 2007, 11:54pm UTC](https://community.zeek.org/t/how-to-count-concurrent-connections/1247/4 "2007-10-14T23:54:17Z")

</div>

> No, it is not 🙂 I only want fully established tcp connections. I

(Ok, sorry, I misunderstood you and thought that you do want to  
count all connections.)

> connection\_established() to detect new connections,  
> connection\_state\_remove() for decreasing the counter and a set of  
> conn\_id to ensure that a connection is removed only once.

Yeah, that's actually the best approach then.

> I tried out the built-in resource\_usage() as well, it gives pretty  
> much the same results as the new\_connection() approach:

Right, that makes sense because it also counts all currently active  
connection independent of their state.

> 1184669772.382840 total: 00125000 concurrent: 67299 max\_TCP\_conns: 122752 num\_TCP\_conns: 67299  
> 1184669772.672518 total: 00126000 concurrent: 67767 max\_TCP\_conns: 67768 num\_TCP\_conns: 67767
> 
> After looking into the code this seems to happen exactly when the  
> underlying PDict object does a table resize.

Yepp, that looks indeed like a bug in the accounting code. While the  
resize is on its way, there are actually two tables kept internally  
and it seems the code calculates the max size wrong during this  
time.

Robin

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex011/uploads/zeek/original/1X/f09d732bc2cc7c7cc7e35db67cf4e1d5233ce7a7.png) [@system](https://community.zeek.org/u/system)\
**Post date:** [May 6, 2022, 3:38pm UTC](https://community.zeek.org/t/how-to-count-concurrent-connections/1247/5 "2022-05-06T15:38:23Z")

</div>


