getting netstat info from within program
*article and comment trail imported from previous forum platform.
Submitted by hsu | 11/6/2009 5:44am
Hi. This is my first post so apologies in advance if it is in any way inappropriate for this forum.
Is there a way I can get the information provided by netstat, specifically the ip address of a client connection, from within my tcpiip router acting as a server?
I've developed support for a protocol which needs to detect the client connection and send an invitation to start an application level 'session' but have some load balancers between my router and the remote computer which poll with rapid connect/disconnects and I need to distinguish between these 'polls' and the 'permanent' connection established by the remote end.
The router code is single threaded and cannot be changed. I have noticed that netstat only ever shows one connection on my port and if I could access this information from within my router then I could determine which connections to ignore.
Obviously the load balancers are there to provide some sort of connection protection and therefore the ip address of the machine which connects my router to the remote end may change so I cannot simply use pre-configured ip_address checking.
I'd be grateful for any ideas.
COMMENT 1: Comment by Paul Green | 11/6/2009 8:30am
You have come to the right place!
I am not entirely certain which aspects of the netstat information you are interested in. We do supply sample code on the VOS anonymous FTP site for accessing the netstat information. Please be aware that if you want to retrieve the per-socket information, your program will have to wade through all active connections until it finds the one it is looking for. You will need to determine whether you can perform this lookup in a reasonable amount of time. Note that this sample code, like all code on the VOS anonymous FTP site, is unsupported by Stratus Customer Service.
The description of how to retrieve the netstat data is available at ftp://ftp.stratus.com/pub/vos/network/stcp_statistics.txt.
On the other hand, if all you need is to know the IP address of the other end of the current TCP/IP connection, there are documented and supported function calls that retrieve that information relatively quickly. Take a look at the getpeername() function in the OpenVOS STREAMS TCP/IP Programming Manual (R420) on http://stratadoc.stratus.com.
COMMENT 2: Comment by Noah Davids | 11/6/2009 11:24am
First, let me confirm that the "router code" is running on a V-series with the STCP TCP/IP stack? If not please be more specific about the environment.
Assuming that this is STCP code and all you are interested in is the IP address, the function getpeer name will return the IP address of the remote host connected to a socket. You can find the documentation for getpeername in the OpenVOs STREAMS TCP/IP Programmer's Guide, on the web at http://stratadoc.stratus.com/vos/17.0.1/r420-08/wwhelp/wwhimpl/js/html/w...
COMMENT 3: Comment by hsu | 11/11/2009 5:59am
Let me try to provide a little more detail. I don't have much experience with comms stuff so please excuse any incorrect terminology.
This is STCP code but running on a Continuum under VOS 14.7.2ab.
Six 'load balancers' are configured to connect to my router, one of which is connected to the actual remote system I want to deal with, and from which I receive keep alives, and the others do zero length polling every six seconds (connect/disconnect) to ensure my router is still available and provide DR capability.
The particular protocol I am supporting requires that in certain scenarios when a connect is detected, my router must send an OPEN SESSION request. The problem I have is that I cannot determine which load balancer is connected to the party I want to deal with and therefore I send out OPEN requests with each connection, even the zero length polling. Each OPEN request has a sequence number and this is causing my router to get out of sync with the actual connection I want to service.
I have noticed however, that whenever I run netstat, I only see one connection, similar to below:
tcp 0 0 *:5700 *:* LISTEN
tcp 0 0 17x.1x.1x.1xx:5700 1x.1xx.1xx.5x:15227 ESTABLISHED
Of course it may be that I just haven't caught the 'polling' connects when I've run netstat but if what is shown above is what I should see under the setup I've described, then if I could get hold of the information, specifically the ip address of the 'ESTABLISHED' connection (1x.1xx.1xx.5x), then I could ignore connects from the other 5 load balancers.
Thanks again, hsu.
COMMENT 4: Comment by Noah Davids | 11/11/2009 11:11am
If the polls are just a connect/disconnect you would have to be very lucky to see one in netstat. You could run packet_monitor and see the connects and disconnects. Try "packet_monitor -numeric -time_stamp -filter -port 5700".
If you are going to ignore the connections from the other load balancers am I correct in assuming that you only have 1 valid application layer connection at a time? How do you tell when the remote host has lost its connection and whats to reestablish- you cannot assume that the load balancer will have dropped the previous connection? What do you do if there are no connections, it would seem in that case that all 6 load balancers would be sending keep alives, are you ignoring all of them?
You can use the getpeername function to get the IP address and port number of a connected socket. You could write something that executes the netstat command, puts the data in a file and then parses the file. Other than these two approaches I can't think of anything.
If you can change the protocol you could do the keep alives on a different port or have an keep alive message that you can recognize and ignore.
You could also keep track of the sequence number assocaited with a socket so that socket always uses the same sequence number. That way new connections with new sequence numbers would not cause problems with existing connections.
COMMENT 5: Comment by Paul Green | 11/11/2009 1:36pm
Hsu, after reading your additional description, my feeling is that you have a design problem, not a coding problem. I believe that a better design would be to ensure that load balancers and "are you alive?" pokes should be transparent to your application. These things are noise to your code. If you get rid of them, you will just be left with the sessions that you care about. From what you have said, your code already correctly handles these "good" cases.
Alternatively, the code that is poking you to see if you are still working could be redesigned to follow the correct handshake protocol of your application; once again, you would have a single flow of logic in your code. It might terminate the session early, but at least it wouldn't require any special case in your logic.
You aren't going to get anywhere with looking at the netstat data. By the time you retrieve it and process it, it will be out of date. Any information that you need on an existing connection can be retrieved via getpeername, as both Noah and I have described.