"port in use" for wine-based lan app for 60s after shutdown

Questions about Wine on Linux
Locked
qd01a
Level 1
Level 1
Posts: 7
Joined: Fri Jun 13, 2014 1:26 pm

"port in use" for wine-based lan app for 60s after shutdown

Post by qd01a »

I'm running several windows-based server apps under wine 1.6.2 on ubuntu 14.04 lts, and while they generally work great, I have one issue I haven't been able to resolve. If I have open connections to a LAN port (say port 5678), I have to wait 60 seconds after shutting the app down before restarting it, or else I will get "port in use". I've tried everything I could find online to no avail. Interestingly, if I do the same with netcat (ie. nc -l -p 5678), and kill it with an attached connection, it will start right up again *immediately* without a problem (no port in use messages), so the issue definitely seems to be wine-related (perhaps because wineserver is still active for other apps?).

Instead of explaining further, and to avoid being offered things to try that I've already done, I've including the list of links / posts containing all the different things I've tried to do to deal with this (including REUSEADDR):

http://www.cyberciti.biz/faq/linux-comm ... ait-state/
http://www.serverschool.com/dedicated-s ... -iptables/ <-- still doesn't kill it!
http://serverfault.com/questions/212093 ... -time-wait
stackoverflow.com/questions/6426253/tcp-tw-reuse-vs-tcp-tw-recycle-which-to-use-or-both
http://stackoverflow.com/questions/2143 ... -reuseaddr
http://stackoverflow.com/questions/8893 ... tw-recycle <-- only recycle worked, but could cause too many other problems...
User avatar
olivierfrdierick
Level 5
Level 5
Posts: 258
Joined: Thu Sep 13, 2012 12:09 pm

Re: "port in use" for wine-based lan app for 60s after shutd

Post by olivierfrdierick »

TCP/IP stuff is beyond me.
Have you tried the app on native Windows to see if it behaves differently?
qd01a
Level 1
Level 1
Posts: 7
Joined: Fri Jun 13, 2014 1:26 pm

Re: "port in use" for wine-based lan app for 60s after shutd

Post by qd01a »

Runs perfectly on native Windows, port is immediately re-accessible right after app shutdown and restart.
qd01a
Level 1
Level 1
Posts: 7
Joined: Fri Jun 13, 2014 1:26 pm

Re: "port in use" for wine-based lan app for 60s after shutd

Post by qd01a »

Thanks dimesio, that's definitely the same bug. I even tried building SO_REUSEADDR into the windows app, and unfortunately nothing worked to solve this for me either.
qd01a
Level 1
Level 1
Posts: 7
Joined: Fri Jun 13, 2014 1:26 pm

Re: "port in use" for wine-based lan app for 60s after shutd

Post by qd01a »

I think SO_REUSEADDR is the only current workaround, but for the app (a Delphi TServerSocket) doesn't allow setting the option out of the box, and it must be set before the port is opened (but after the socket is created). I also tried setting tcp_tw_reuse=1 in ubuntu, but that had no effect. Interestingly, even setting tcp_fin_timeout=15 didn't make the wait timeout shorter under wine either.
User avatar
dimesio
Moderator
Moderator
Posts: 13367
Joined: Tue Mar 25, 2008 10:30 pm

Re: "port in use" for wine-based lan app for 60s after shutd

Post by dimesio »

Try the patch in the bug report.
oiaohm
Level 8
Level 8
Posts: 1020
Joined: Fri Feb 29, 2008 2:54 am

Re: "port in use" for wine-based lan app for 60s after shutd

Post by oiaohm »

qd01a there are things that are not really simple to mess with.
http://man7.org/linux/man-pages/man7/tcp.7.html
tcp_fin_timeout (integer; default: 60; since Linux 2.2)
This specifies how many seconds to wait for a final FIN packet
before the socket is forcibly closed. This is strictly a
violation of the TCP specification, but required to prevent
denial-of-service attacks. In Linux 2.2, the default value
was 180.
This is not a really sane item to mess with.

http://blog.netherlabs.nl/articles/2009 ... t-reliable
Luckily, it turns out that Linux keeps track of the amount of unacknowledged data, which can be queried using the SIOCOUTQ ioctl(). Once we see this number hit 0, we can be reasonably sure our data reached at least the remote operating system.
Linux will refuse to close a port completely as long as the kernel has a record of unacknowledged data that has not timed out yet on TCP. Because when Linux closes a port completely it also deletes the matching TCP cache.

nc -l -p 5678 or equal sitting on the port results in the tcp packet cache of the port being continual so resend of packet requests don't result in new FIN packets having to be sent. SO_REUSEADDR also results in tcp packet cache being continual. But there is a downside to using SO_REUSEADDR under Linux as well. SO_REUSEADDR places a lock that the same process cannot open the same port at the same time in a different section of the code. Writing a small watch dog program or nc -l -p [port] >/dev/null can be the correct way forwards.

This is differences between Linux TCP stack and Windows TCP stack. Linux TCP stack is a very strict little item that does not like particular things. When Linux TCP stack is being a problem you may have worse problems. I guess your program under Windows has not been using SO_LINGER either.

SO_LINGER tells Linux when it can dispose of the unacknowledged data when closing port otherwise it waiting on TCP packet timeouts.

tcp_tw_reuse and tcp_fin_timeout have zero effect on problems caused by unacknowledged data.

qd01a the fact nc works to prevent blockage I would be very suspect that the program only requires SO_LINGER set. This will cause the program to delay on close but the port to be properly free when the application closes. SO_LINGER only effect closing of port no other operation.

If your application is something requiring security with the packets removed from memory when you are done you will not use SO_REUSEADDR. Yes this is the classic two ways to skin the cat. SO_REUSEADDR trys to address the problem on open of port and SO_LINGER address same problem on close of port. SO_LINGER is the more secure path. The fact SO_REUSEADDR is not working for you do attempt SO_LINGER. Under windows setting SO_LINGER is a good idea not to have magical data pop out of the tcp cache causing what the heck errors.

Sometimes when Linux is being strange there is a real issue its trying desperately to protect you tail from. Windows vs Linux here is also a problem as well. Windows does fail to acknowledge all received TCP packets after a FIN message is received(yes breach of TCP spec) so Linux to Windows port on Linux side can jam waiting because you did not close with a SO_LINGER option. Of course this is not Linux doing the wrong thing because Windows also has a habit of requesting resends on packets after receiving the FIN packet as well. Yes setting SO_LINGER may have teeth.

qd01a you are not alone most people don't think about unacknowledged data and what is happening to it.
qd01a
Level 1
Level 1
Posts: 7
Joined: Fri Jun 13, 2014 1:26 pm

Re: "port in use" for wine-based lan app for 60s after shutd

Post by qd01a »

I managed to get it working by extending Delphi's TServerSocket with a ReuseAddr property, and even added the ability to bind to specific ports. It now works under WINE as well (no more port in use on bind() anymore when shutting down and quickly restarting apps!) Just wanted to throw this out there again in case it can save someone else a load of time troubleshooting.

I'd be happy to share the code changes too if anyone feels it could help them (just message me with your email).
qd01a
Level 1
Level 1
Posts: 7
Joined: Fri Jun 13, 2014 1:26 pm

Re: "port in use" for wine-based lan app for 60s after shutd

Post by qd01a »

oiaohm, I had tried adjusting tcp_fin_timeout and it oddly had no effect (for me at least) on the timeout time under Wine. I looked further into why the problem didn't seem to plague netcat (I even tried the Win32 version via Wine) and what they were doing was SO_REUSEADDR as well. I was able to extend Delphi's TServerSocket to do this (as described in my last post) and now it seems to work perfectly! Thanks everyone for the help / input!
qd01a
Level 1
Level 1
Posts: 7
Joined: Fri Jun 13, 2014 1:26 pm

Re: "port in use" for wine-based lan app for 60s after shutd

Post by qd01a »

hi oiaohm, just re-read more carefully your last post. Took me a few reads to fully absorb it. Really contained a few gems in there, so thank you for that! I went ahead and changed SO_REUSEADDR to SO_LINGER in my modified TServerSocket class, and as you suggested it also seems to work now under linux / ubuntu as well! Based on your explanation, it does sound like it's the best solution to fix this problem. Thanks again for your in-depth post and suggestions!
Locked