The Unix Heritage Society mailing list
 help / color / mirror / Atom feed
From: torek@torek.net (Chris Torek)
Subject: [TUHS] Sockets and the true UNIX
Date: Thu, 21 Sep 2017 13:36:38 -0700	[thread overview]
Message-ID: <201709212036.v8LKac1u063236@elf.torek.net> (raw)
In-Reply-To: Your message of "Thu, 21 Sep 2017 09:17:44 -0700." <20170921161744.GD25650@mcvoy.com>

>... I've never been fond of the socket API though I
>am sympathetic, it's easy to do the easy parts as /dev/tcp but as I
>recall there are all sorts of weird cases that don't fit.

There's no reason it could not be done literally with entries
similar to /dev ones, since each socket() takes some arguments
(domain, type, protocol) which could be represented as directly
as:

    /socket/domain/type/protocol_or_default

for instance.  For the typical s = socket(PF_INET, SOCK_STREAM, 0)
you would open "/socket/inet/stream/tcp".  To distinguish
between UDP and RDP you'd open "/socket/inet/dgram/udp" vs
"/socket/inet/dgram/rdp".  Of course these days there's a
<type> constant for reliable datagram, and some of these are
just overcomplicating things: /socket/inet/tcp, /socket/inet/icmp,
etc., would actually suffice, but there's an obvious one
to one mapping from "socket" arguments to strings under
"/socket" or whatever top level name you want.

More fundamentally, a socket itself is only "half initialized".
It's neither bound to any local address, nor connected to any
remote address.  The BSD kernel interface introduced two
system calls, bind() and connect(), to let you specify these
two halves.  But these two calls are wrong!  It needs to be
*one* call, that does both operations simultaneously, so as to
allow you to specify that you want the system to provide the
local or remote address.  You supply one or both.  To supply
only one, pass in a NULL for the other one.

 * You supply only the remote address: "I want to connect to
   someone and I know their address, so just pick a local one
   that works."  This is currently written as connect().

 * You supply only the local address: "I want to be a server."
   This is currently written as bind() followed by listen()
   followed by a series of accept()s.  There's no reason for
   a separate listen() call (it takes a "backlog" argument but
   in practice everyone defaults it and the kernel does strange
   manipulations on it.)  This also knocks out the need for
   SO_REUSEADDR, because the kernel can tell at the time of
   the call that you are asking to be a server.  Either someone
   else already is (error) or you win (success).

 * You supply both halves at the same time.  (This is the
   special case FTP requires.)  "I want to connect to someone
   and I know he expects me to be address <L>.")

   This is a rare special case.  We need a way to reserve an
   address.  But it's rare, let's make *it* the complicated one.

   If you supply both halves at the same time, you can pass
   pointers to two all-zero addresses, both local and remote.
   This is different from passing in a NULL ("I don't care"): it
   means "I do care, get me an address" (reserving it) along with
   "I can't actually connect yet".

   Now you have the "3/4ths done" socket.  You know what your
   local address will be.  You give this to the remote, and
   call the system call again with the other guy's IP address
   this time.

   That's not optimal (sometimes the local address you want to
   use depends on the remote address you will use), but it's what
   the existing system calls give you anyway, as you can't call
   connect() first, you must call bind() first.

Also, the profusion of system calls (send, recv, sendmsg, recvmsg,
recvfrom) is quite unnecessary: at most, one needs the equivalent
of sendmsg/recvmsg.

So we could right away do this:

   bind(), listen(), connect()     =>     setconn()
   send(), sendmsg()               =>     sendmsg()
   recv(), recvfrom(), recvmsg()   =>     recvmsg()

even without figuring out how to properly implement /dev/tcp
or whatever.

Of course, it's a bit late. :-)

Chris


  reply	other threads:[~2017-09-21 20:36 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-21 16:01 Ian Zimmerman
2017-09-21 16:07 ` Chet Ramey
2017-09-21 16:10 ` Larry McVoy
2017-09-21 16:20   ` David Edmondson
2017-09-21 16:25   ` Clem Cole
2017-09-21 16:27     ` Larry McVoy
2017-09-21 16:37     ` [TUHS] Sockets and the true UNIX [ actually carping about streams ] Jon Steinhart
2017-09-21 18:26   ` [TUHS] Sockets and the true UNIX Chet Ramey
2017-09-21 16:13 ` Jon Steinhart
2017-09-21 16:17   ` Larry McVoy
2017-09-21 20:36     ` Chris Torek [this message]
2017-09-21 18:56   ` Bakul Shah
2017-09-21 19:13     ` Steve Simon
2017-09-21 19:31       ` Bakul Shah
2017-09-21 20:15         ` ron minnich
2017-09-21 20:34           ` Clem Cole
2017-09-21 23:26   ` Dave Horsfall
     [not found] <mailman.1105.1506026200.3779.tuhs@minnie.tuhs.org>
2017-09-22 10:36 ` Paul Ruizendaal
2017-09-22 14:32   ` Clem Cole
2017-09-22 14:42     ` Chet Ramey
2017-09-22 14:47       ` Chet Ramey
2017-09-22 14:52         ` Lars Brinkhoff
2017-09-22 14:49       ` Larry McVoy
2017-09-22 14:57         ` Chet Ramey
2017-09-22 18:14           ` Chris Torek
2017-09-22 18:43             ` Clem Cole
2017-09-22 19:08             ` Chet Ramey
2017-09-22 20:57               ` Chris Torek
2017-09-24 18:04                 ` Chet Ramey
2017-09-22 18:00   ` Chris Torek
2017-09-25 17:57 Norman Wilson
2017-09-25 18:55 ` Clem Cole

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201709212036.v8LKac1u063236@elf.torek.net \
    --to=torek@torek.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).