"port in use" for wine-based lan app for 60s after shutdown
"port in use" for wine-based lan app for 60s after shutdown
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...
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...
- olivierfrdierick
- 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
TCP/IP stuff is beyond me.
Have you tried the app on native Windows to see if it behaves differently?
Have you tried the app on native Windows to see if it behaves differently?
Re: "port in use" for wine-based lan app for 60s after shutd
Runs perfectly on native Windows, port is immediately re-accessible right after app shutdown and restart.
Re: "port in use" for wine-based lan app for 60s after shutd
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.
Re: "port in use" for wine-based lan app for 60s after shutd
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.
Re: "port in use" for wine-based lan app for 60s after shutd
Try the patch in the bug report.
Re: "port in use" for wine-based lan app for 60s after shutd
qd01a there are things that are not really simple to mess with.
http://man7.org/linux/man-pages/man7/tcp.7.html
http://blog.netherlabs.nl/articles/2009 ... t-reliable
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.
http://man7.org/linux/man-pages/man7/tcp.7.html
This is not a really sane item to mess with.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.
http://blog.netherlabs.nl/articles/2009 ... t-reliable
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.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.
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.
Re: "port in use" for wine-based lan app for 60s after shutd
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).
I'd be happy to share the code changes too if anyone feels it could help them (just message me with your email).
Re: "port in use" for wine-based lan app for 60s after shutd
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!
Re: "port in use" for wine-based lan app for 60s after shutd
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!