For those of you following along ... this has been a few days of debugging.
jaketompson1 was on the right track ... I'm still not entirely sure what is going on, but we're comparing Putty on Windows and mTCP Telnet and the traces from Windows show TCP keepalive packets are being sent from the remote side after just a minute or two. That is kind of nuts, as keepalive is optional and it usually doesn't kick in for two hours. I suspect the ISP is injecting the keepalive packets, as I'm not seeing them when I connect to the same machines. waulu13 is also seeing this behavior on several different remote machines, which also implicates the ISP.
mTCP responds correctly to keepalive packets, but the networking setup at times hid the mTCP machine behind another machine that might not have been forwarding those packets, so it wasn't always an apples-to-apples comparison. But I have seen evidence of mTCP responding to keepalive packets when it is directly connected to the router. mTCP does not send keepalive packets because, well, they are supposed to be optional.
I'm just waiting on confirmation that my quick&dirty keepalive support in mTCP worked, and then I want to get the name of the ISP to see if they have a history of shenanigans like this.
----
Another thing to be aware of ... Unicode processing. If you have Unicode enabled on the mTCP side and a BBS sends a high-bit character (ASCII above 127) as they often do for graphics characters, the UTF-8 parsing will try to interpret and eat those characters. It will look like the connection has hung. You need to disable Unicode/UTF-8 parsing on the mTCP side if you have a BBS that sends graphics characters.