Hacker News new | past | comments | ask | show | jobs | submit login
SSH uses four TCP segments for each character you type (hyfather.com)
100 points by ultimoo on May 30, 2013 | hide | past | favorite | 41 comments

Well, that's just called "remote echo" and it doesn't have much to do with SSH. It's just that the remote is in charge of drawing the character on the screen if needed.

If you change to "local echo" it would cause problems with programs such as vi which will interpret certain characters (such as hjkl) as special commands and won't actually draw them on the screen.

If you start a remote program that just "eats" your input without updating the terminal (like a password prompt) you won't see the 2nd tcp roundtrip.

You'd have the same behaviour with a serial link, rsh, telnet or anything else.

I think I saw a custom SSH client on hn some months ago that would try to compensate high network latencies by echoing the characters locally while waiting for the remote reply. It would then undo the local echo and use the "authoritative" reply instead.

The article isn't as judgmental as the headline makes it sound. It notes that in practice, it only sends three segments across the wire, and that's what I'd expect from telnet, too.

Indeed, I didn't mean to sound harsh either. I just wanted to point out that this is in no way specific to SSH as the headline seems to imply.

You didn't seem harsh. In retrospect, I should have made that as a top-level comment instead of a reply.

Are you thinking of Mosh? http://mosh.mit.edu/

I have used Mosh as my primary remote access client for a few months on my "on-the-go" laptop, and I must say that the user experience is very good.

In a lot of scenarios, the latency is not much of an issue, but on wlan/3g, this very fast become very noticeable. In the few cases since, I've used ssh on wireless, I suddenly find myself noticing how much of an issue the sudden feedback delay might be at some times.

Not only is mosh great for latency, but it's also great for laptops because of IP roaming. These days I have a dedicated Terminal window with a permanent Mosh session to my Linode. The Mosh session never shuts down (unless I'm rebooting), no matter how often I put my laptop to sleep, or go between home and work.


The only obvious downside to Mosh I've seen so far, is that a lot of enterprisy firewalls tend to block UDP traffic.

That's the one, and after watching the video again it's actually more clever than my "local echo" description even though it's part of it.

For a high latency situation if you're text editing there is EMACS TRAMP mode, and probably others similar that buffer the file locally, which will also solve the responsiveness problem.

Exactly. In the modern world latency concerns so outstrip bandwidth issues that it's actually much saner to copy the whole file across the wire than it is to try to edit it locally. The curmudgeon in me finds that amazing sometimes.

Yup. For command line work I usually don't mind but for text editing I find any perceptible latency incredibly grating. SSHFS is another solution that doesn't need anything special installed on the remote end. It's a pity Plan9 didn't take off, I think it hides this kind of pointless drudgery.

I think it would be neat if SSH provided an API or a set of special characters so that the remote shell could tell SSH to switch back and forth between remote and local echo. For example, bash could tell SSH to begin local echo mode after it finishes printing the prompt, and end local echo mode when the user enters a key sequence that requires remote processing, like Tab or Return. vim could enter local echo mode when the user enters insert mode and leave when the user presses the Esc or Return, etc.

Perhaps this extra complexity would lead to all sorts of strange bugs though.

There already exists such an API at the TTY level (see man 4 termios). You can switch between so called "canonical" mode where the input is buffered by lines or non-canonical to get the input byte by byte without waiting. You can also switch echo on and off among other things.

I don't think ssh sends that back to the client terminal though, but I must say I'm not really sure how that's handled. On one hand I'd like to know better how unix TTYs work, but on the other I value my sanity so I'm probably not looking back into those just now :).

This is right, but the canonical/non-canonical distinction is all or nothing. Bash echos most characters, but it needs to treat a handful, like tab, up, and down, specially so it (or readline probably) puts the terminal in non-buffered mode and ends up echoing the normal characters. I read the GP as suggesting that there should be a way for bash to indicate which characters were "normal" and should be buffered and echoed and which it wants to see immediately. It's an interesting idea, but of course such a mechanism would require coordination between the kernel's terminal interface, bash/readline, and ssh in order to get a marginal improvement in network efficiency.

Ah, providing it at the terminal level does make more sense (that was probably obvious to anyone with any familiarity with the basics of Unix terminals, sorry), and now that I hear it I'm not surprised it already exists :)

In that case, I guess this functionality would be implemented similarly to the example you mentioned of stopping the client from sending every keystroke at a password prompt, right? It seems like it would be strange for ssh to send the 'toggle echo' signals to the client, but not the 'toggle canonical mode' signals (which the client could also handle in a useful way).

Are you thinking of EXTPROC/LINEMODE? There's outstanding patches to bash, telnet, and ssh to support these, which enables local line-editing that works smarter than just local echo.

TIOCPKT_IOCTL(EXTPROC) and TIOCSIG support landed in Linux kernel 2.6.36: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux....

SSH is an interesting set of solutions that appear on the surface to be horribly inefficient but after a tiny amount of digging are actually okay.

I had to write an SSH terminal inside a browser, and it was full of "why the heck did they"s followed ten minutes later by "oh, that's why"s.

Do you have any anecdotes to share, or a blog post or something? I'd be quite interested to read about your thought process.

One interesting thing about this is how it can lead to timing attacks which leak information about your keystrokes. There's a great paper [1] which gives some examples. One more reason to use pubkey authentication for SSH.

[1] http://users.ece.cmu.edu/~dawnsong/papers/ssh-timing.pdf

I believe that passwords are not transmitted like this in SSHv2 because of that very attack (not to say there are not overwhelmingly good reasons to use public key authentication anyway).

They can still get you if you invoke SSH on the remote, as the password is sent to the remote machine one character at a time, then forwarded on to your ultimate destination all at once.

That is what public key/agent forwarding is for.

This will explain it better than I ever could: http://www.unixwiz.net/techtips/ssh-agent-forwarding.html

Good point, though I imagine that this issue could be fixed in SSH as long as the password is not being echoed (which it should not be).

Ironically, I think it's actually slightly easier for an eavesdropper to detect that your keystrokes are part of a password if the password is not being echoed.

They could potentially use this information to know the length of a password, which would make brute-forcing easier. A very hypothetical attack, but fun to think about! Less effective than a $5 wrench, no doubt.

Thanks for this link, that was very educating! I had no idea that you could do stuff like this.

I'm honestly wondering why this is here.

Specifically, the section on "Why not send whole commands" made me wonder who this is targeted at, its pretty basic UNIX stuff to know how an Async ASCII terminal works.

Then, obviously, it's targeted at people who don't know "pretty basic UNIX stuff". Which to a few points of precision is everyone. And, guessing, a significant enough portion (to be interesting article) of HN readers.

you can also use linemode. it works for telnet and, uhm, it sort of work for ssh through a 3rd party patch. it sends whole commands AND supports everything. That's because its not just a dumb echo, and require terminal support on the server side.

mosh actually does something in between (and thus have display errors sometimes)

it's hardly surprising that you send one packet, get one ack and then, when the shell wants to update the display sends a packet and then gets one ack. how should it be different? (leaving aside udp-protocols for similar functionality as mosh)

Just a question...Doesn't TCP confirm the data sent, UDP doesn't and has a lower overhead, right?

Correct, UDP doesn't ACK, but you also don't know if the packet reached the server for the same reason. UDP is great for streaming data that may arrive out of order or where packets can be lost and it isn't critical, such as streaming video, but it is awful if you need to be sure the data got to its destination.

You're generally spot on, but I figured I'd clarify a bit of terminology since it can be so confusing in our field. Generally, TCP is referred to as a "stream" based protocol because it guarantees, amongst other things, that all packets will arrive in the order in which they were sent, as you've mentioned.

UDP _is_ great for "streaming" data, meaning data sent piecewise over a continuous connection (or, at least, emulated connection) because packet loss / reordering is an acceptable loss, since a minor blip is less destructive than pausing the video. In this type of setting, packets that arrive out of order (i.e. a packet that was sent earlier arrives after a packet sent after it has been received) are thrown out and the process keeps on chugging.

Thank you, that's what I was thinking about UDP. I knew UDP was good for video and raw data packets. Disappointing that Webworkers, Video, and Audio streams for HTML5 still use TCP.

BTW: awesome handle - south park, lol :)

You mean websockets? Those try to support all the legacy of HTTP proxies (which I don't understand the point of).

whoops, yeah I meant websockets (was coding a worker when I commented lol)

That is correct yes. UDP doesnt have ports either.

It definitely has ports. Right there, in the packet header.


Both UDP and TCP have ports. ICMP does not.

The set of Source IP:Source Port:Target IP:Target Port is how most connections are differentiated. All four of those combine to form a unique connection identifier.

I always used to turn off delayed acks when tunnelling X11 over SSH, for substantial improvement in interactive responsiveness.

Why is this surprising?

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact