socket program is able to connect to the port which is still in TIME_WAIT - php-socket

I have written a very simple socket server.
It listens in post 63254.
First i did a socket_create, socket_bind, socket_listen so here a connection is listening.
Then in a loop i do the socket accpet. so here another listen.
the read function reads untill i input exit.
after that the resource id by socket_accept closes.
and then the main connection closes.
when i checked this process in TCPview after closing all connections i can still see the system process showing TIME_WAIT for post 63254
if i again run the socket server program it is connecting and when one full process is over all the connection is closed and the program terminated and now i can see another TIME_WAIT for the same port. but still i could connect to the same port the third time.
in stackover question answer it is said that connection cannot be done for port which is in wait state.
I opened firefox browser it opened 4 connections.
when i closed it all closed and the system process showed 4 time waits for 2 minutes.
all time wait stays for 2 minutes and disappears.
so what i conclude is for every connection close the time wait is occurs and cannot be avoided.
i read many posts in stack overflow flow but still wasn't sure of it.
i run the following code in command line.
My server Code
<?
error_reporting(E_ALL);
set_time_limit(0);
ob_implicit_flush();
$str = '';
$buff = '';
$s = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if(!$s)die('Unable to create socket');
if(!socket_bind($s,'127.0.0.1',63254))
die("\nTrying to Bind: ".socket_strerror(socket_last_error()));
if(!socket_listen($s,1))
die(socket_strerror(socket_last_error()));
while(1)
{
$acc = socket_accept($s);
if(!$acc)die(socket_strerror(socket_last_error()));
// echo "\n".gettype($acc);
if(!$acc)die(socket_strerror(socket_last_error()));
while(1)
{
$str = socket_read($acc,512);
$buff.= $str;
echo $str;
// echo '::'.gettype($str);
if($str===false)die(socket_strerror(socket_last_error()));
if($str=="exit\r\n")break;
}
// if(!socket_shutdown($acc,2))echo socket_strerror(socket_last_error());
socket_close($acc);
if(preg_match('/exit/',$buff))break;
}
//echo "\nConnection closed by server\n";
//if(!socket_shutdown($s,2))echo socket_strerror(socket_last_error());
socket_close($s);
?>
The client code
<?
set_time_limit(0);
$f = fsockopen('127.0.0.1',63254,$a,$b,10);
if(!$f)die('cannot connect');
echo "\nConnected: \n";
do{
$buff = fgets(STDIN);
fwrite($f,$buff);
}while($buff!="exit\r\n");
fclose($f);
?>
need suggestions to improve a better client server if this is not sufficient. this code is just a child's play. just trying to understand the way communication works.

In stackover question answer it is
said that connection cannot be done
for port which is in wait state.
I don't know what answer you're referring to, but you cannot bind to a port which is in TIME_WAIT state. If you are a server you can use setReuseAddress() to overcome this. If you're a client you have to wait, or use a different outbound port, or best of all don't specify an outbound port at all, let the system find one. You are a server so this doesn't apply to you.
I opened firefox browser it opened 4
connections. when i closed it all
closed and the system process showed 4
time waits for 2 minutes. all time
wait stays for 2 minutes and
disappears.
But those are client ports. Outbound ports. At your server they were inbound ports, and there was also a listening port on the same port number. As long as there is a listening port, an inbound connnection can succeed.
so what i conclude is for every
connection close the time wait is
occurs and cannot be avoided.
TIME_WAIT occurs when you are the end that sends the close first. If you are the end that received the close, and closed in response, your port doesn't go into TIME_WAIT at all.

Related

UDP port is not free after closesocket call (Windows)

I have two listening sockets (created by calls to socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)), at this moment they are maintained from one thread.
After creating, they have to be closed (closesocket(...)) and reopened again on the same ports. But bind(...) call returns error 10048 WSAEADDRINUSE on one of these sockets (the second one is opened successfully), and I see by using netstat that the UDP port stays open (closesocket(...) returned no error, SO_REUSEADDR always set to TRUE on all sockets). And this "closed" UDP port stays open as long as the 2nd socket is open (they have no relation, but the "closed" port is closing a second after the 2nd socket is closed).
Let's summarize:
Open sockets and bind them to ports 8888 and 9999.
Close 8888 socket, create new socket, bind it to port 8888 -> success.
Close 9999 socket, create new socket, and try to bind it to port 9999 -> error WSAEADDRINUSE.
Close 8888 socket -> success.
After about a second after #4, port 9999 is freed (by observing in external tool).
I have discovered something similar to my problem: https://stackoverflow.com/a/26129726/10101917, but in my case moving all socket operations to one thread does not solve the problem.
What is happening here?
I have found what caused this problem. The thing I have programmed is the DLL. I have discovered, that another DLL from this app is using QProcess class of Qt library version 5.7.1. I have checked sources of Qt and discovered that this class actually starts process with bInheritHandles set to TRUE. When I manually have reset this value to FALSE all issues were gone.
It is obvious that the issue was caused by the following: one of UDP socket handles was inherited by child process and that process didn't let socket handle to be closed, until that process stop.
Thanks to this comment for pointing to the solution.

Socket programming, what about "CLOSE_WAIT", "FIN_WAIT_2" and "LISTENING"?

I am writing a socket based C application which seems to behave in a very unstable way.
The code is standard socket handling on TCP port 6683, and I know it has worked before. Instead of mentioning the source code, I believe the most interesting are the results of the netstat -aon command:
When it worked fine, the results of the netstat -aon| grep 6683 command were:
TCP 127.0.0.1:6683 127.0.0.1:50888 CLOSE_WAIT 6128
TCP 127.0.0.1:50888 127.0.0.1:6683 FIN_WAIT_2 3764
When it does not work anymore, the results of the netstat -aon | grep 6683 command are:
TCP 127.0.0.1:6683 0.0.0.0:0 LISTENING 7800
Does anybody know the meaning of the mentioned "netstat" results, what this might mean for the socket handling and what can I do in order to return to the situation giving the first results?
Thanks
From Microsoft's Support Website:
FIN_WAIT_2 Indicates that the client just received acknowledgment of the first FIN signal from the server
LISTENING Indicates that the server is ready to accept a connection
CLOSE_WAIT Indicates that the server has received the first FIN signal from the client and the connection is in the process of being
closed
Based on the above, you know that in your first case the server has received the client's FIN, and the client has received the ACK from sending the FIN to the server.
However, in the second case the server is ready to accept a connection, which to me sounds like you haven't established your TCP connection yet.
Without really knowing what your C program is trying to do, it's hard to diagnose your issues here, but I would take a look at the documentation for netstat and go from there.
From the netstat documentation :
FIN_WAIT2
Connection is closed, and the socket is waiting for a shutdown from the remote end.
CLOSE_WAIT
The remote end has shut down, waiting for the socket to close.
The LISTENING state is just the server socket waiting for clients. This is a normal behavior for a listening server socket (which is not the same as the connection server socket).
You can see that the side with FIN_WAIT2 is closed and waiting for the other, but the side with CLOSE_WAIT, is currently closing, but not yet closed. Based on the LISTENING socket, the client is closed, and the currently closing side is the server. The server is probably waiting because there is data to read that was not yet read. It can't close the socket without data loss, which is unacceptable for TCP. The connection should close normally after all the data left on the server side is read.
Thanks for the fast responses. Meanwhile I have found what was going wrong:
My application was a server application, creating a client process, and setting up a TCP socket for communicating with that client process (which was done using the C commands:
snprintf(buf, 1024, "client_process.exe %s %d", szListenHost, iListenPort);
CreateProcess(NULL, buf, NULL, NULL, FALSE, dwCreationFlags,
NULL, NULL, &sin, &pin);
Sometimes this went fine, sometimes not, based on the place from where I launched my server process: when I launched it from the official directory, it was working fine. When I launched it from my development environment, it was not working.
The reason for this was very simple: in my development environment, the "client_process.exe" file was not present in the current directory.
I have now copied the "client_process.exe" into that directory and added an extra check:
int return_value = CreateProcess(NULL, buf, NULL, NULL, FALSE,
dwCreationFlags, NULL, NULL, &sin, &pin);
if (return_value == 0) {
printf("The client_process.exe has not been started successfully.\n");
word error_return_value = GetLastError();
printf("The corresponding error value is:[%d]\n", error_return_value);
if (error_return_value == 2) {
printf("The client_process.exe is not present in the current directory.\n");
}
}
Kind regards

interface is down but netstat still shows the connection established? [duplicate]

This question already has answers here:
Java socket API: How to tell if a connection has been closed?
(9 answers)
Closed 5 years ago.
When I'm using e.g. PuTTY and my connection gets lost (or when I do a manual ipconfig /release on Windows), it responds directly and notifies my connection was lost.
I want to create a Java program which monitors my Internet connection (to some reliable server), to log the date/times when my internet fails.
I tried use the Socket.isConnected() method but that will just forever return "true". How can I do this in Java?
Well, the best way to tell if your connection is interrupted is to try to read/write from the socket. If the operation fails, then you have lost your connection sometime.
So, all you need to do is to try reading at some interval, and if the read fails try reconnecting.
The important events for you will be when a read fails - you lost connection, and when a new socket is connected - you regained connection.
That way you can keep track of up time and down time.
Even though TCP/IP is "connection oriented" protocol, normally no data is sent over an idle connection. You can have a socket open for a year without a single bit sent over it by the IP stack. In order to notice that a connection is lost, you have to send some data on the application level.(*) You can try this out by unplugging the phone cable from your ADSL modem. All connections in your PC should stay up, unless the applications have some kind of application level keepalive mechanism.
So the only way to notice lost connection is to open TCP connection to some server and read some data from it. Maybe the most simple way could be to connect to some FTP server and fetch a small file - or directory listing - once in a while. I have never seen a generic server which was really meant to be used for this case, and owners of the FTP server may not like clients doing this.
(*) There is also a mechanism called TCP keepalive but in many OS's you have to activate it for all applications, and it is not really practical to use if you want to notice loss of connection quickly
If the client disconnects properly, a read() will return -1, readLine() returns null, readXXX() for any other X throws EOFException. The only reliable way to detect a lost TCP connection is to write to it. Eventually this will throw an IOException 'connection reset', but it takes at least two writes due to buffering.
Why not use the isReachable() method of the java.net.InetAddress class?
How this works is JVM implementation specific but:
A typical implementation will use ICMP ECHO REQUESTs if the privilege can be obtained, otherwise it will try to establish a TCP connection on port 7 (Echo) of the destination host.
If you want to keep a connection open continually so you can see when that fails you could connect to server running the ECHO protocol yourself rather than having isReachable() do it for you and read and write data and wait for it to fail.
You might want to try looking at the socket timeout interval. With a short timeout (I believe the default is 'infinite timeout') then you might be able to trap an exception or something when the host becomes unreachable.
Okay so I finally got it working with
try
{
Socket s = new Socket("stackoverflow.com",80);
DataOutputStream os = new DataOutputStream(s.getOutputStream());
DataInputStream is = new DataInputStream(s.getInputStream());
while (true)
{
os.writeBytes("GET /index.html HTTP/1.0\n\n");
is.available();
Thread.sleep(1000);
}
}
catch (IOException e)
{
System.out.println("connection probably lost");
e.printStackTrace();
}
Not as clean as I hoped but it's not working if I leave out the os.writeBytes().
You could ping a machine every number of seconds, and this would be pretty accurate. Be careful that you don't DOS it.
Another alternative would be run a small server on a remote machine and keep a connection to it.
Its probably simpler to connect to yahoo/google or somewhere like this.
URL yahoo = new URL("http://www.yahoo.com/");
URLConnection yc = yahoo.openConnection();
int dataLen = yc.getContentLength() ;
Neil
The isConnected()method inside Socket.java class is a little misleading. It does not tell you if the socket is currently connected to a remote host (like if it is unclosed). Instead, it tells you whether the socket has ever been connected to a remote host. If the socket was able to connect to the remote host at all, this method returns true, even after that socket has been closed. To tell if a socket is currently open, you need to check that isConnected() returns true and isClosed() returns false.
For example:
boolean connected = socket.isConnected() && !socket.isClosed();

How to deal with network port abuse in sockets

I have a web app written in c++ using TCP/IP over standard network sockets, running on Linux. The service is open to the wild and woolly internet.
Periodically I get bursts of abusive requests from spammers running automated scripts. I can detect these and close down the socket. Right now I just do a polite socket close like I would do to any valid request that has completed, with a socket lib close like this:
close( mSocket );
But sometimes closing the socket normally notifies the spam script that the socket connection has terminated, and they immediately initiate another fraudulent request.
What is the best way to terminate a TCP/IP connection that cleans up the open socket on my system, but leaves the remote party hanging. That is I want to close a socket in the way that is lowest cost for me, but highest cost for them.
#Nicholas Wilson:
Using TCP_REPAIR seems like a good idea. When a socket is closed in TCP_REPAIR mode no FIN or RST packet is sent. The remote socket is left hanging. I'm going to try it and report back. Here is my (untested) code:
if ( abuse )
{
int aux = 1;
if ( setsockopt( mSocket, SOL_TCP, TCP_REPAIR, &aux, sizeof( aux )) < 0 )
reportError( "Tried to do a rude socket close... but could not turn on repair mode.\n" );
}
close( mSocket );
I'll report back if this works. (#edit: tested answer below)
# The "leave the socket open" idea:
This works but is sub optimal. The attacker has the ability to saturate your system with open sockets. Each request creates a new socket that is left open. With DOS attack you eventually run out of sockets.
Then there is also the problem with managing the open sockets:
Just don't close it. Open sockets last forever. Cost for attacker: high - they get no fin. Cost for me: higher. All my file descriptors eventually get used.
Spawn a thread per socket to sleep 10 minutes and then close the socket. Cost for attacker: high - they get no fin. Cost for me: higher. While I eventually do close the socket, for each request I have a socket used up for longer than the attacker does, and I have the overhead of a thread.
Spawn a thread that handles expiring all abused sockets. Cost for attacker: high - they get no fin. Cost for me: higher. Like 2, lots of sockets held open. Overhead of a single thread to manage it. Code complexity, annoyance.
Ok, did some research and I have an answer that works for me, based on TCP_REPAIR. It is a little more complex than I thought at first:
if ( abuse )
{
// read some bytes from the spammer - to establish the connection
u32 tries = 20;
while ( tries )
{
sleep( 1000 );
char tmpBuf[32];
s32 readCount = recv( mSocket, &tmpBuf[0], 32, 0 );
if ( readCount > -1 ) break;
tries--;
}
#ifdef TCP_REPAIR
int aux = 1;
if ( setsockopt( mSocket, SOL_TCP, TCP_REPAIR, &aux, sizeof( aux )) < 0 )
{
reportError( "could not turn on repair mode" );
}
#else // !TCP_REPAIR
// no TCP REPAIR - best we can do is an abort close
struct linger so_linger;
so_linger.l_onoff = 1;
so_linger.l_linger = 0;
if ( setsockopt( mSocket, SOL_SOCKET, SO_LINGER, &so_linger, sizeof so_linger ) < 0 )
{
reportError( "Cannot turn off SO_LINGER" );
}
#endif // TCP_REPAIR
}
close( mSocket );
At the kernel level, the TCP stack will either send a FIN or RST packet if you close a connection, no matter how you do it ( with either close or shutdown ). Either way the attacker is notified that you closed the connection.
We want to silently close the connection and let them wait around to realize you're not answering... because we're vindictive.
TCP_REPAIR is a new socket API designed to allow you to 'freeze' a socket, save its state, and reload the socket state on another process or even another system. Under normal usage the client would never know their connection was transferred elsewhere.
But we can abuse this API, we put the socket in repair mode, but don't save its state and never restore it. When we close the socket in repair mode - it gets silently deleted.
This works for abusive requests that have already begun. That is we've read the spammer's request and decided it was fraud and TCP_REPAIR killed it.
But if you block requests by IP, right after connect, without first reading the socket, somehow the remote party is notified. They get an RST. Or probably something in the connection never quite completes and the remote system aborts the request almost immediately.
So we first read a few bytes from the hacker's socket. In my case the socket is already in non-blocking mode. But if not you want to set the socket to non-block, or else you open yourself up to the hacker opening connection, but sending no packets and leaving your server hanging - like you plan to do to him. If after a few microseconds you don't get a packet you shut him down anyway.
But if you read a few bytes from him, then his program is left waiting for a response from you that never comes.
TCP_REPAIR is only available on Linux Kernels 3.5 and above. Below that the best I can do is a 'dirty' socket close. This is where instead of sending him a FIN you send him and RST. It will look to him like a valid connection was never established. To do this, you turn off SO_LINGER, to essentially break the socket connection close handshake, and then call close.
Works like a charm, point your browser here:
http://oroboro.com/fail
Chrome at least will hang there for 5-10 seconds. Looking at my logs where I was getting 10 hits per second - he's only able to hit me every 10 seconds or so. Load on my system from this: 0.
See ya sucker!
When you detected a malicious client, I would recommend you to not just close the connection, but to also refuse any new connections originating from the same IP address.
What you can do at least is blacklist the IP in your application. Keep a list of banned IP addresses and immediately close any accepted socket which originates from an IP on that list.
But to protect more of your resources, it would be even better to block the connection further outward in the network architecture. When you are able to do so, notify the gateway router to block it. When that's impossible, try to get the load balancer to block it. Failing that, at least add a rule to the local firewall of the server.
But keep in mind that many such attacks originate from consumer-grade internet connections (with or without the user being aware). That usually means their IP addresses are assigned and regularly re-assigned dynamically. An IP which was used by a spammer a few days ago might now be used by a legitimate user. So IP-based bans shouldn't last forever.
Use this:
#include <sys/socket.h>
int shutdown(int socket, int how);
It will send a RST and close (the connection) immediately. This will make it seem, that there's no service on that port and the attacker will hopefully cease spamming on that port. Call close() to free the handle.
When you detect an abuse
have a pool of sockets for "spammers" whenever you detect abuse you put them in the pot using one of those sockets. if no free socket is available recycle the oldest and just shutdown and close it.
if a connection qualifies as !abuse let them use a proper socket.

c++ detect if the client closed the connection (multi sockets)

In my program I have several sockets on the server. Each socket has its own port. I tried to detect if the client closed the connection with:
signal(SIGPIPE, sig_pipe);
But I have the problem that I don't know on which socket the connection was closed.
Is there some method to get it to know?
More about code:
In main program I started 3 Sockets on different ports. Accept, receive and send for each socket I put in one thread. So I have 3 threads at the end.
Thank you.
You should setup SIGPIPE to be ignored (see sigaction(2)) and handle EPIPE error code from write(2) and the likes.
Note, that reading zero bytes from TCP socket is the real indication of the other side closing the connection.