Author Topic: Keeping Track of "Any Network Connection Established"  (Read 9620 times)

Offline danh

  • Newbie
  • *
  • Posts: 28
    • View Profile
Keeping Track of "Any Network Connection Established"
« on: June 04, 2008, 11:08:26 PM »
In my project I want to use an LED to show whether there are any ongoing TCP sessions (or, more generally, any "network connection").

I've tried using a global counter that is incremented when a session is established, and decremented when a session is closed; so, if the counter is greater than zero, then it means there is some session established.

I haven't really gotten this to work well. What happens is that the counter ends up getting decremented multiple times when a session closes. I searched out the places in tcp.c where the listening application is sent the TCP_EVENT_CONNECTED and TCP_EVENT_CLOSED, but it seems like in some cases several of the TCP_EVENT_CLOSED locations are hit when the session is closed. The behavior I see is that if I just open and close a Telnet session, the status works fine. But if I copy files to the unit via FTP while the Telnet session is still open, the status gets changed back to "no session established' (i.e. the counter gets decrement to <= 0), even though the Telnet session has not been closed.

I realize another way to do this would be to update the global counter at the application level (i.e. in the Telnet server, and Web server, and FTP server, and so on, but it would obviously be better for it to be more generic.

Can anyone suggest a way to do this?

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: Keeping Track of "Any Network Connection Established"
« Reply #1 on: June 05, 2008, 11:46:44 PM »
Hi

I think that the most reliable method would be to use the TCP state. The state is always changed using the call fnNewTCPState() - as follows:
    switch (ptr_TCP->ucTCP_state = ucNextState) {

This means that you can count just before this by doing something like
if ((ptr_TCP->ucTCP_state <= TCP_STATE_LISTEN) && (ucNextState > TCP_STATE_LISTEN)) {
  count++;                                              // connection taking place
}
else if ((ptr_TCP->ucTCP_state > TCP_STATE_LISTEN) && (ucNextState  <=  TCP_STATE_LISTEN)) {
    count--;                                            // connection terminated
}


This may result in a reliable method (?)
However note that sockets often go to the TCP_STATE_TIME_WAIT state for 2 minutes when a connection is terminated. Sometimes the stack allows this socket to be used from this state for further connections (to avoid all available sockets temporarily blocking due to this 2 minute timeout) and so this may be an exception (again ?). Also you may decide to count the TCP_STATE_TIME_WAIT state as already closed.

Regards

Mark


Offline danh

  • Newbie
  • *
  • Posts: 28
    • View Profile
Re: Keeping Track of "Any Network Connection Established"
« Reply #2 on: June 10, 2008, 08:48:55 PM »
Mark,

That looks sensible. However, I find that the count does get incremented as expected, but it never gets decremented, even after numerous telnet and web connections getting opened and closed.


Code: [Select]
static void fnNewTCPState(TCP_CONTROL *ptr_TCP, unsigned char ucNextState)
{
    ptr_TCP->ucRetransmissions = TCP_DEF_RETRIES;                        // standard retries if the message timesout

#ifdef TRY_NEW_CODE
    if((ptr_TCP->ucTCP_state <= TCP_STATE_LISTEN) && (ucNextState > TCP_STATE_LISTEN))
        tcp_session_count++;
    else if((ptr_TCP->ucTCP_state > TCP_STATE_LISTEN) && (ucNextState <= TCP_STATE_LISTEN))
        tcp_session_count--;
#endif

    switch (ptr_TCP->ucTCP_state = ucNextState) {

Does this make any sense to you?

Dan

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: Keeping Track of "Any Network Connection Established"
« Reply #3 on: June 10, 2008, 09:24:55 PM »
Hi Dan

I think that is due to the TCP_STATE_FIN_WAIT_2 state.

If your socket experiences a passive close (the server or peer closes) it will immediately close and so the counter gets decremented. [See also the diagram uTasker-TCP.PDF in \Documents] Then it seems to works.

However, check out what happens when moving to the TCP_STATE_TIME_WAIT state:

    switch (ptr_TCP->ucTCP_state = ucNextState) {
        case TCP_STATE_TIME_WAIT:                                        // we do not want to block applications in this state so we give them the chance to reuse the socket immediately if they want to
            ptr_TCP->event_listener(ptr_TCP->MySocketNumber, TCP_EVENT_CLOSED, ptr_TCP->ucRemoteIP, ptr_TCP->usRemport);
            ptr_TCP->usTransmitTimer = 2*TCP_MSL_TIMEOUT;
 


The HTTP server will be called and immediately sets its socket back to the listening state, therefore you never get the transition. Exactly the same is done by the TELNET server...

I tried the following:
Code: [Select]
#ifdef TRY_NEW_CODE
    if((ptr_TCP->ucTCP_state <= TCP_STATE_LISTEN) && (ucNextState > TCP_STATE_LISTEN))
        tcp_session_count++;
    else if((ptr_TCP->ucTCP_state > TCP_STATE_LISTEN) && ((ucNextState <= TCP_STATE_LISTEN) || (ucNextState == TCP_STATE_TIME_WAIT)))
        tcp_session_count--;
#endif

I tried a number of HTTP and Telnet sessions and at the end the count was zero (it was of course incremented on each connection). I wonder whether this will solve it for you?

Regards

Mark


Offline danh

  • Newbie
  • *
  • Posts: 28
    • View Profile
Re: Keeping Track of "Any Network Connection Established"
« Reply #4 on: June 11, 2008, 12:33:21 AM »
Yes, that seems to make it work as desired.

Thanks a lot, Mark!