Messages in this thread | | | From | "Lord Satanus of Acheron" <> | Subject | How do I detect abruptly broken connections? [when other ends lose their modem connection to their ISP] | Date | Tue, 28 Dec 1999 14:56:46 +1100 |
| |
I have a few users who are located in what is probably TCP/IP hell... India. Their mean time to carrier loss is about 6 minutes during the day, and they can sometimes hold the line for a whopping 2-3 hours after around midnight.
So... I used to provide POP3 service via UW-Pine 4.1's POP3 package - only, the sudden and unpredictable disconnections would leave stuck sockets [and POP3 processes] sometimes for quite some time [which with the UW-Pine package, locks the user out of his mailbox]. I've since changed pop3 server to one which is designed for security first and foremost anyhow [Solar Designer's lean and mean popa3d]. It has more aggressive timeouts in the code, which I keep set pretty low [2 minutes].
In addition to POP3, I provide a special sendmail port for these users to make use of, which ends up connecting to a customised redir program run out of inetd.
About 2 times out of 3, the redir process times out rather than properly closing. [The mail transfer succeeds, so it's clear that the entire connection succeeds and closes otherwise normally, but the client may not be properly closing the SMTP connection at the "end" of the transaction. The Indian client is using Outlook Depressed 4.5 [for Macintosh]]. I don't care too much about that, but it's an interesting data point.
My question is this:
In perusing the code for lots of networking daemons and such, when they call select(), I rarely if ever see a list of FDs passed to the "exceptions" part of select() [the third parametre, after the writefd list]. Would passing an fdlist to the exceptions parametre provide for more readily detected socket faults? [Naturally, I'd have to add some code to check the exceptionsfdlist and handle any FD_ISSET's appropriately.]
I would like to be able to detect broken sockets with more reliability and less ambiguity. Lots of daemons seem to "handle" it by just setting a timeout (either passed to select() or via an alarm() mechanism). This seems kludgey to me - and besides, if I turn down my timeouts this way too low, I run the risk of blowing connections that have short-term low performance.
What can I do to allow two-way socket communications to reliably detect when the other end has "died"? I can't alter the actual data protocol since these are well-established and well outside of my jurisdiction to control [SMTP and POP3]. What do you guys suggest?
Are there kernel tuning parametres that would enable this to be done more easily? Would turning down keepalive intervals accomplish this? (and ensuring that the sockets have SO_KEEPALIVE on) - are keepalives sent over "active" connections [connections which are actually "flowing" and receiving ACK packets]? I'd hate to diminish bandwidth by jamming my outbound network traffic with needless keepalive traffic. The kernel has it set to 2 hours by default - I have the bad feeling that keepalives aren't best done too often.
Any pointers would be greatly appreciated. I'd like a "proper" solution rather than alarm-timeouts/etc.
At the moment, the bandaids have solved the problems - but in a wider scope of things, I'd like to solve the real problem. Timeouts to me, are to handle "idleness" and the like. I would personally prefer to know the difference between a "broken link" and a timeout.
One other thing... I have wu-ftpd-2.6.0 configured to use keepalives, however, they never seem to kill broken links either. The ftpd processes wait for the master timeout to die (which is implemented as an alarm interrupt). What's the deal? Has SO_KEEPALIVE truly been deprecated to dysfunctionality in the kernel at some point? If not, how do I actually get it to work? I don't have the freedom to change the ftp/smtp protocols, so whatever solution there is, it can't really alter those protocols. I *DO* recall when doing some i/o on a Solaris machine to unreliable end-points, it would pretty reliably detect broken sockets with code that was compiled pretty stock. (I didn't have kernel/root access on the machines, and I didn't do any tweaking of any kind).
Thanks, =Rob=
PS: Linux 2.2.13+SolarD's no-stack-exec, libc5 (began life as slack4), and I'm behind a firewall which allows connections to the appropriate ports.
PPS: I'd appreciate a cc: on any replies. -- The reply-to-address is real and will expire on 12:01AM 1-Feb-2000. Spammers: You will lose your network access. Guaranteed. 102 domains, 374 web-accounts, and 567 dialup ISP accounts flushed
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |