Winsock

You installed a stack, told it a phone number, and listened to two modems find each other. Then the screeching stopped, and for about two seconds nothing happened. Four things were happening, in order, and each one could not start until the one below it had finished. The line had to become a link. You had to prove who you were. You had to be lent an address, because you did not have one. And only then could anything open a connection.

Winsock was not any of those four. It was the thing you dropped in so that Trumpet and Netscape and Eudora did not each have to carry them.

Four things, in order

Each of these is a real protocol with a real specification, and each one refuses to run until the one below it has finished. That is not this page being strict. It is what the documents say: CHAP's challenge comes “after the Link Establishment phase is complete”, and IPCP packets sent before their turn “should be silently discarded”. Work up the ladder in the panels below and watch the rungs unlock.

    The negotiation

    Three things that could happen when you dialled. Step through them and watch the automaton move. Every transition below is a lookup in the table further down, which is the table printed in RFC 1661; nothing on this page decides anything for itself.

      Each event, the transition the table gives for it, and what the automaton did
      eventfromtoactions

      Opened. The layer above has been told the link is up, and a browser can finally do something.

      The table it is reading

      Ten states across, sixteen events down, a hundred and sixty cells. This is section 4.1 of RFC 1661, transcribed and checked cell by cell against the document. The cell being used right now is marked.

      The LCP state transition table

      In the RFC's own words: State transitions and actions are represented in the form action/new-state. And The dash ('-') indicates an illegal transition.

      Proving who you were

      Two protocols did this job over dial-up, and the difference between them is the whole reason one of them is still in use. Both are computed here for real: the CHAP response is a genuine MD5 over the identifier, the secret and the challenge, in that order, and the page checks its own MD5 against the five vectors printed in RFC 1321 before it shows you anything.

        Being lent an address

        This is the step people forget. The link was up and you were authenticated and you still had no IP address, because you had never had one: the number belonged to a pool at the other end of the phone line and you were lent one for the length of the call. You asked for 0.0.0.0, which is how the option says you have none and would like one, and the answer came back as a refusal carrying the address. Four packets.

          And then a connection

          The same shape again, four layers up. Eleven states, nineteen arrows, printed as figure 6 of RFC 793 in September 1981 and unchanged since. The machine at the top of this page agrees that there is a wire; this one agrees that there is a conversation. Both do it by reading a table.

            the eleven states, and where you are

              And what the connection was for

              ESTABLISHED is where most explanations of TCP stop, and it is the least interesting thing TCP does. The interesting thing is handing an application a stream of bytes in order, with nothing missing, over a network that drops whatever it likes. The mechanism is small enough to hold in your head, and it has one property people are consistently surprised by.

              “The acknowledgment mechanism employed is cumulative so that an acknowledgment of sequence number X indicates that all octets up to but not including X have been received.” Cumulative. There is no way to say I have 1 and 3 but not 2. A receiver missing one segment can only keep repeating the number of the hole.

              Every segment on the wire, and what the receiver could do with it
              whatseqSND.UNASND.NXTackreceiver

              And then something to say

              Four layers get you a connection, and a connection is not the internet. It is a pipe with nothing in it. What a browser put in the pipe in 1994 was HTTP, and HTTP was smaller than people remember: RFC 1945 is dated May 1996 and it writes down what came before it as the simple form. One method. No headers. A response that is the document and nothing else, ended by the server hanging up.

              what you send

              what comes back

              What that costs a crawler

              A person who lands on an error page reads it and leaves. A crawler stores it. Under the simple form there is no status line, so the only thing a crawler can do is look at the words and guess. Five pages, fetched under each version, with the same five outcomes at the far end.

              The same five fetches under each version of the protocol
              pathreallyHTTP/0.9 believedHTTP/1.0 believed

              What came in the box

              All five rungs were something you assembled yourself until somebody sold them together. In 1994 O’Reilly & Associates and Spry, Inc. shipped Internet in a Box, and it was, in the encyclopaedia’s careful wording, “one of the first commercially available Internet connection software packages available for sale to the public.”

              What was inside maps onto this page almost rung for rung. “The IBox software included the Winsock program and TCP/IP stack that were needed to connect a computer running Microsoft Windows to the Internet in 1994” — that is the four layers above. A licensed copy of NCSA Mosaic called AIR Mosaic — that is the fifth, the thing with something to say. And a subscription to InterServ, Spry’s own dial-up service, because a stack with nobody to call is furniture.

              The name is the argument. Everything this page makes you climb one rung at a time was, by 1994, a box you could buy.

              How this machine was built, what it is measured against, and where it was wrong first: the engineering notebook.

              Why there are two Ack states

              A link is not one agreement, it is two. You send a Configure-Request saying what you want; the other end sends one saying what it wants. You are Opened only when both have been answered, and the automaton needs to remember which half has already happened. Ack-Rcvd means your request was granted and theirs is still outstanding. Ack-Sent means you granted theirs and yours is still outstanding. Either one, plus the missing half, gets you to Opened, which is why both of them and only both of them lead there.

              That is the sort of thing a state table makes obvious and prose makes hard. Look down the Opened column of the matrix: everything that can arrive on a working link has an answer, and the only illegal events are coming Up when you are already up, and a timer expiring when no timer is running.

              What made it a machine you could install

              None of this was new in 1994. What was new was that an ordinary person could buy a modem, install one piece of software, and end up with a computer that was on the internet rather than a terminal talking to something that was. The stack did the negotiation above and then handed every application a socket, so the browser did not have to know about any of it. Install it once and everything worked, instead of every program shipping its own networking and none of them agreeing.

              That is the change this domain is named for. The automaton is what the stack was doing in the two seconds before the first page loaded.

              What is real here, and what is not

              Four layers, and the gaps between them are real gaps

              Reaching Opened means the link exists. It does not mean you have an address, and the page now goes on to the three steps that follow. What is genuinely modelled is each protocol's own decision: PAP and CHAP are computed rather than acted out, IPCP's four packets are produced by a peer holding a pool rather than replayed from a script, and TCP's transitions are looked up in figure 6. What is not modelled is anything between the layers. There is no timing, no retransmission, no MTU, and no traffic at all once the connection is open. The subject is how each layer decided it was ready, not what it then carried.

              The table is transcribed, and it was hard to transcribe

              RFC 1661 prints the table as plain text in two blocks, and its columns stop lining up when a cell is wider than its column. Splitting a row on whitespace merges two cells of the RCR+ row, where "sta/2" and "irc,scr,sca/8" are separated by a single space. Slicing at the header positions cuts the Close row in the wrong places for the same reason. What this page does instead is take each cell as a token by its shape and require every row to produce exactly one cell per state, which is a check the other two methods fail loudly rather than quietly getting wrong. The test parses the archived RFC and compares all hundred and sixty cells.

              The restart counter moves, and the timers do not

              There is no clock here. The Timeout events are things you press, not things that happen after a Restart timer expires, because a page that made you wait three seconds for each retransmission would be teaching patience rather than protocol. The counter that the actions Initialize-Restart-Count and Zero-Restart-Count move is real and is shown; the timer that would decrement it is not modelled.

              LCP's options are a name here; IPCP's are a mechanism

              The difference between RCR+ and RCR- is whether the options the other end asked for were acceptable, and deciding that is real work: maximum receive unit, authentication protocol, magic number, and the rest of section 6. In the LCP panel you pick which of the two events arrived, and the decision behind it is not modelled. One layer up it is: the IPCP panel actually holds a pool of addresses, decides whether the one you asked for is in it, and Naks with one that is. That is the option negotiation this page owes you, done for the option that mattered most.

              The MD5 is real, and it is here as a 1994 artifact

              CHAP's response is a genuine MD5 over the identifier, the secret and the challenge, in that order, computed in the page. It is written out because SubtleCrypto does not offer MD5 and is right not to. It is checked three ways before anything is shown: against the five vectors printed in RFC 1321's own appendix A.5, against a different implementation over four hundred inputs, and at every length either side of a 64-byte block boundary, which is the only place a hand-written MD5 tends to go wrong. Nothing on this site authenticates anything, and MD5 has been unfit for that purpose since the 1990s.

              The challenges are a counter, not a random number

              RFC 1994 says the challenge value must change every time it is sent, and here it does. It is not unpredictable, though: it comes from a small generator with a fixed seed, so the same page gives the same run twice. That is deliberate. A demonstration you cannot repeat is one nobody can check, including the test suite. A real authenticator needs the value to be unguessable as well as different, and this one only manages different.

              Figure 6 is not all of TCP, and RFC 793 says so first

              The eleven states and nineteen arrows are transcribed from figure 6, and the RFC is explicit that the picture is partial: it “illustrates only state changes, together with the causing events and resulting actions, but addresses neither error conditions nor actions which are not connected with state changes”. So a state and event the figure does not join is refused here rather than guessed at, and the page says which. One real consequence: the simultaneous close, where both ends send FIN at once and FIN-WAIT-1 goes straight to TIME-WAIT, is not in figure 6 and is not here. Also missing, because they are not state changes: sequence numbers, windows, retransmission, and everything else TCP is actually for. And RFC 793 itself is no longer the current specification: RFC 9293 replaced it in August 2022, consolidating four decades of corrections. It keeps this diagram. So “unchanged since” on this page is a claim about the eleven states and nineteen arrows, not about the document around them, which has been rewritten.

              The addresses are invented; the way they were handed out is not

              165.113.59.201 is not anybody's, and the pool has two addresses in it because that is enough to show a Nak. The mechanism around them is the RFC's: you send a Configure-Request naming 0.0.0.0, and the peer “can provide this information by NAKing the option, and returning a valid IP-address”. The count of packets, and the fact that a refusal is how you got an answer, are real. The numbers inside them are furniture.

              Nothing here is Winsock's own specification

              Winsock is the API a Windows application called to use a socket, and its specification is a separate document from this one. It was not reachable when this page was built: it is not on bitsavers, the current vendor documentation is modern developer material rather than the Windows Sockets 1.1 specification of January 1993, which is the version this era ran, and the archive that most likely holds it was refusing automated requests. So this page is named for the thing people installed and models what that thing was doing, rather than pretending to document an interface nobody here has read. If the specification turns up, the honest move is a second machine and not a quiet expansion of this one.

              Sources