tcp-ip@ucbvax.ARPA (07/16/85)
From: stanonik@nprdc.arpa (Ron Stanonik) 4.2bsd/rlogin's use of reserved ports for user authentication seemed the cause of a little problem here. While a user was rlogin'ed from a sun to a vax, the sun crashed. After the sun rebooted the user was unable to rlogin to the vax (connection timed out?), apparently because the vax still thought the previous connection from the sun was established, and the sun was trying to reuse the same reserved port. (rlogin chooses the source port from the first available port starting at 1023, working downward.) Of course killing the login on the vax marked the connection closed and cleared up the problem, but there must be a better/nonmanual way. Have we've overlooked a 4.2bsd mod which allows rlogin or the tcp's to sort this out? Thanks, Ron Stanonik stanonik@nprdc
tcp-ip@ucbvax.ARPA (07/17/85)
From: imagen!geof@su-shasta.ARPA The TCP source port for rlogin should be chosen in a manner that makes it unlikely for the same port to be reused twice in a row. "Twice in a row" includes the possibility that the ports will be chosen before and after crashes, so a RAM counter is inappropriate. 4.2's apparent method of grabbing closest port below 1024 that is not currently used tends to choose the same port twice in a row with high probability in a number of cases. This algorithm is not suitable for choosing TCP port numbers (Gosh, I hope the kernel does a better job!). A better technique is to generate some random number in the right range of ports each time a port number is needed, and regenerate another if you fail. A simple expediency is to use the low-order bits of a millisecond clock. A user process on Unix (with a one-second clock) might use: long now; time(&now); sleep(1); port = htons( (now + getpid()) % 512) + 512 ); to get a number in the range [512,1024), or port = htons( (now + getpid()) | 0x8000 ); to get a port number in the "temporary" range. - Geof
tcp-ip@ucbvax.ARPA (07/17/85)
From: imagen!geof@su-shasta.ARPA The choices that I suggested are all things that I have done in implementations of various protocols (which need to choose port numbers for the same reason TCP does), and that have worked well. I personally think that low bits of clocks are more random than pseudo-random number generators. To get a really random number from a PRNG, you have to seed it with a random number (egg or chicken?). The obvious thing to do is seed the PRNG with the clock. Hmm.... why don't you just use the clock...? Using a clock also makes sense from a more theoretical point of view. In most situations the times at which connection requests are made are much more like independent random variables than anything else that a program can get its hands on. Especially when you have a fast clock. Of course, any choice of port is actually put inside of a loop which makes sure that the port is Currently unique. You can't be sure of not choosing the same port twice Sequentially unless you have hardware that is stable across system crashes (hey, the clock is more likely to fit that criterion than anything else, isn't it...?). If "portChoice()" chooses a port number using whatever algorithm you have in mind (but "1023" is probably not a good algorithm), then you need one of the following program fragments (sometimes this fragment is embodied in the kernel, which is an excellent idea): i := portChoice(); while portInUse(i) do i := i + 1; or i := portChoice(); while portInUse(i) do i := portChoice(); The one to use depends on the nature of you portChoice() procedure. If it is based on a one second clock, then maybe the first program fragment is better. If it is based on a microsecond clock, then the two are probably equivalent, but I like the second better, perhaps for irrational reasons. In any event, if you have a good portChoice() algorithm, you will almost never go through the loop more than once, and if you often go through it more than twice, rewrite portChoice, because it isn't working as it should. - Geof