I have written a program in C++
and i need to check if a TCP port is truely empty.
This is the function :
int checkport(char* host, char* port, int timeout)
{
int sock;
struct sockaddr_in sin;
int result = 0;
sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET;
sin.sin_port = htons(atoi(port));
sin.sin_addr.s_addr = inet_addr(host);
fd_set fdset;
struct timeval tv;
fcntl(sock, F_SETFL, O_NONBLOCK);
int connect_result = connect(sock,(struct sockaddr*)(&sin),sizeof(struct sockaddr_in));
FD_ZERO(&fdset);
FD_SET(sock, &fdset);
tv.tv_sec = timeout;
tv.tv_usec = 0;
int select_result = select(sock + 1, NULL, &fdset, NULL, &tv);
// printf("connect = [%d] | select = [%d]\n",connect_result,select_result);
if(select_result == 1)
{
int so_error;
socklen_t len = sizeof so_error;
getsockopt(sock, SOL_SOCKET, SO_ERROR, &so_error, &len);
// printf("so_error = [%d] \n",so_error);
if(so_error == 0)
{
//Is connected
if(hitdebug >= 4) puts("CONNECTED");
if(hitdebug >= 2) printf("[%s:%s] OPEN\n",host,port);
result = 1;
}
else
{
if(hitdebug >= 4) puts("CONNECT_ERROR_1");
result = 0;
}
}
else
{
if(hitdebug >= 4) puts("CONNECT_ERROR_2");
result = 0;
}
close(sock);
return result;
}
The problem is that is detecting only LISTEN port, i want a port to be 100% true and even detect ESTABLISHED, TIME_WAIT, etc ...
Output :
connect = [-1] | select = [1]
so_error = [111]
50983 TEST=[0]
tcp 0 0 1.2.3.4:50983 4.4.4.4:22 ESTABLISHED
connect = [-1] | select = [1]
so_error = [111]
43343 TEST=[0]
tcp 0 0 1.2.3.4:43343 4.4.4.4:22 ESTABLISHED
connect = [-1] | select = [1]
so_error = [0]
64000 TEST=[1]
tcp 0 0 1.2.3.4:64000 0.0.0.0:* LISTEN
tcp 0 0 1.2.3.4:47669 1.2.3.4:64000 TIME_WAIT
connect = [-1] | select = [1]
so_error = [111]
54674 TEST=[0]
connect = [-1] | select = [1]
so_error = [111]
54665 TEST=[0]
For me an empty port is when i do a netstat -an | grep 12345 | wc -l
and i see 0, not even a FIN_WAIT
How can i accomplish that?
Thank you.
if (the_port_is_free(port_number)) {
/* is the port free at this point? */
}
The correct answer is "who knows?" Sure, it was free a nanosecond ago when the control was somewhere in the function the_port_is_free
, but is it free now? There are many other processes around, perhaps one of them took the port half a nanosecond ago?
This is called a race condition. Every programmer should understand the concept.
It is precisely because of this problem the_port_is_free
is not provided by your OS: it only would give you false expectations, not correct answers. You cannot know whether the port is free now and, more importantly, will be free in a nanosecond when you decide to bind it. The only way to bind the port is to go ahead and try binding it.
This approach applies to a whole bunch of situations. Whenever there's a shared resource of any kind, there's usually no function that tells you if it's OK to grab it. The only way to get it is to go ahead and try.
Just try to bind
the port for listening - if it fails (with SO_REUSEADDR
off, which is the default), then the socket is either in active use or in one of the WAIT states.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With