Provided by: libgensio-dev_2.3.5-1build2_amd64 bug

NAME

       gensio - How to specify a gensio

SYNOPSIS

       <type>[(options)][,gensio|terminaloptions]

DESCRIPTION

       gensio  stands  for GENeral Stream Input Output.  It provides an abstraction for all kinds
       of stream I/O, and even makes some packet  I/O  look  like  stream  I/O  (like  UDP).   In
       particular, gensio makes it easy to create encrypted and authenticated connections.

       The  gensio  library specifies a connection (gensio) using a string format.  This consists
       of a gensio type, optional options in parenthesis.  For a terminal gensio (one that is  at
       the  bottom  of  the  stack),  it  may take more options separated by a comma.  For filter
       gensios (ones not on the bottom of the stack) another gensio must be specified  after  the
       comma.  For instance:

              serialdev,/dev/ttyS0

       specifies a serial port gensio.  Or:

              tcp(readbuf=100),localhost,4000

       specifies  a  TCP  connection  with  a  100  byte  read buffer, to connect to port 4000 on
       localhost.  Or:

              telnet,tcp,localhost,4000

       specifies a telnet filter on top of a TCP connection.

       When specifying a gensio, you can add quotes (single or  double)  to  remove  the  special
       meaning for some characters, so you can have commas in options and such.  They may also be
       escaped with a "\".  For instance, if you are specifying a laddr in an sctp  address,  you
       need to do this.  The following address:

              sctp(laddr=localhost,4001),localhost,3023

       will  result  in  a  failure  because  the option splitting code will split at the commas.
       Instead, do:

              sctp(laddr="localhost,4001"),localhost,3023

       and it will work.

       Accepter gensios, gensios  used  for  accepting  connections,  as  opposed  to  connecting
       gensios,  are  specified in the same way.  Each individual type can vary, and some gensios
       are only connecting gensios.  The options  can  vary  from  the  accepter  and  connecting
       gensios  of  the same type.  For instance, an accepting TCP gensio does not have to have a
       hostname, but a connecting one does.

       When an accepter gensio receives a connection, it will create an  accepted  gensio.   This
       works  mostly like a connecting gensio, except some functions may be limited.  You may not
       be able to close and then open an accepted gensio.

       The gensio library has a concept of client and server.  The accepted gensios are generally
       considered  servers.   Connecting  gensios are generally considered clients.  Some gensios
       may allow this to be overridden.

       A gensio may be reliable or not.  A reliable gensio will  reliably  deliver  all  data  in
       sequence,  like  TCP.  An gensio that is not reliable may drop data or deliver data out of
       sequence, like UDP.  This can be queried with gensio_is_reliable().

       A gensio may be packet or not.  A packet gensio will exactly match up  writes  and  reads.
       So  if  you  write 15 bytes into one side, a 15 byte read for that data will appear on the
       other side.  A gensio that is not packet will not respect write boundaries, that  15  byte
       write may result in multiple reads or it may be combined with another write into more than
       15 bytes.  Packet I/O requires careful use to make it work correctly.   Particularly,  you
       must  set  the  max read and write size to the same value, and you must accept all data on
       receipt and write complete packets all at once.

       A gensio may be message oriented.  This implementation is stolen from  SCTP  (even  though
       it's  not really supported on Linux at the moment).  It basically means you can explicitly
       mark message boundaries when sending data, and that explicit mark will be set on the  read
       side.   You  do  this  by  adding  an "eom" auxdata on the write; the end of that write it
       assumed to be the end of a message.  If the write does not accept all the data, the  "eom"
       is  ignored,  you  must  write  the  remaning  data again with "eom" set.  You may also do
       partial write of messages and set "eom" at the end.  On the receive side,  "eom"  will  be
       set  when  the  end of a message is delivered.  The data delivered in the receive callback
       will be only the data for that message.  If the user does not accept  all  the  data,  the
       data left in the message is again presented to the user with "eom" set.

       The  options vary greatly between the different gensios.  Each gensio type will be covered
       in a separate section.  Also note that gensio types can be dynamically added by the  user,
       so there may be gensios available that are not described here.

       Unless othersize noted, every gensio takes a:

       readbuf=<n>
              option to specify the read buffer size.

DEFAULTS

       Every  option  to a gensio (including the serialdev and ipmisol options), unless othersize
       stated, is available as a default for the gensios.  You can  use  gensio_set_default()  to
       set  the  default  value used by all gensios allocated after that point.  If you leave the
       class NULL, it will set the base default, which will affect all gensios unless  they  have
       an override.  If you set the class, it will only affect gensios with that class name.

       Be  very  careful  with some defaults.  Setting "mode" default, for instance, could really
       screw things up.

       For string defaults, setting the default value to NULL  causes  the  gensio  to  use  it's
       backup default.

Serial gensios

       Some gensio types support serial port setting options.  Standard serial ports, IPMI Serial
       Over LAN, and telnet with RFC2217 enabled.

       A client serial gensio can set and get  serial  port  options  using  the  sergensio_xxx()
       functions.     Server    serial   gensios   receive   requests   from   the   client   via
       GENSIO_EVENT_SER_xxx events in the callback.

Streams and Channels

       Some gensios support the concept of a stream and/or a channel.

       A stream is delivered as part of the normal data stream of a gensio.  The "default" stream
       will  be  treated normally.  All other streams will have "stream=<x>" given in the auxdata
       to specify which stream to write on or which stream was  read  from.   Streams  cannot  be
       individually flow controlled.

       A channel is a flow of data like a stream, but it can be individually flow controlled.  It
       appears as a new gensio in  the  GENSIO_EVENT_NEW_CHANNEL  callback.   You  can  create  a
       channel  with  gensio_alloc_channel()  and  then open it with gensio_open().  Once open, a
       channel works like a normal gensio.  If you close the main channel for a gensio, the other
       channels  will  stay  open;  the  resources for the main channel will still be kept around
       until all channels are closed.

       See the indvidual gensio description for more information on streams and channels.

PUBLIC KEY CRYPTOGRAPHY

       The ssl and certauth gensios use public key cryptography.  This  section  gives  a  little
       overview  of  how  that works.  You can safely skip this section if you already understand
       these concepts.

       Public key cryptography is used to authenticate and encrypt information at  the  beginning
       of  a  session.   It  is a fairly expensive operation and is not generally used to encrypt
       information after the beginning.

       In public key cryptography, you have three basic things: A private key, a certificate  (or
       public key), and a certificate authority (CA).

       The  private  key  is  just  that:  private.   You  don't  even send your private key to a
       certificate authority for signing of your certificate.  Keep it private,  non-readable  by
       everyone  else.   Protect it, if it becomes known your certificate becomes useless to you,
       anyone can impersonate you.

       The certificate is the public key, and is mathematically associated with a single  private
       key.   It's  just that, public, anyone can use it to test that you have the private key by
       asking you to sign some data.  The data in the certificate (like the Common Name) is  part
       of the certificate.  If that data is modified, the certificate validation will fail.

       The  CA  is  generally a trusted third-party that validates you and signs your certificate
       (generally for a fee).  CAs issue their own public certificates that  are  well-known  and
       generally  available  on  your  system.   The  CA certificates are used to prove that your
       certificate is valid.

   SIGNING
       The process if signing has been mentioned already, but not described.  Basically, you  use
       your private key to generate a value over some given data that proves you have the private
       key.  The certificate is ised to mathematically verify the signature.

       Two things are normally done with this:

       In a public key exchange, the entity wishing to be authorized sends  a  certificate.   The
       authorizing  entity  will  look through it's CA for a certificate that has signed the sent
       certificate.  If the authorizing entity finds a certificate that can be used  to  validate
       the sent certificate, the sent certificate is valid.

       After  that,  the authorizing entity sends some generally random data to the other entity.
       The other entity will take that data, perhaps some other important data that  it  want  to
       make  sure  is  not modified in the transfer, and signs that data.  It sends the signature
       back to the authorizing entity.  The authorizing entity can then  use  the  data  and  the
       signature  to  validate  that  the  sending entity has the private key associated with the
       certificate.

       This is basically how https works.  Note it is the web client that authenticates  the  web
       server,  not  the other way around.  This proves that you are connecting to the entity you
       say you are connecting to.  The authentication of a  web  client  to  the  web  server  is
       generally  done via a different mechanism (though SSL/TLS used by the ssl gensio has a way
       to do it, it is not generally used for that purpose).

       In the web server scenario, data in the certificate  (specifically  the  Common  Name  and
       Subject  Alternate  Name) must match the name of the web page to which you are connecting.
       The ssl and certauth gensios do not do this authentication, that is up to the user  if  it
       is necessary.

   ENCRYPTING
       The  certificate  can  be used to encrypt data that can only be decrypted with the private
       key.  When establishing an encrypted connection, this is  generally  used  to  transfer  a
       symmetric  cryptography  key  from  one  entity  to another (the authorizing entity to the
       requesting entity in the case above).  You could encrypt all the data with the public key,
       but that is very expensive and in our example above would require certificates and private
       keys on both ends.

   SELF-SIGNED CERTIFICATES
       It is possible to create a certificate that can act  as  its  own  certificate  authority.
       This  is  how  ssh works.  You create a public and private key.  You put the public key in
       the .ssh/authorized_keys directory on systems where you want to log in.   The  certificate
       acts  as  both  the  public  key  (as  part  of  the  initial transfer) and the CA (in the
       authorized_key directory) for authorizing you use of the system you are logging in to.

       ssh also stores places it has connected to in .ssh/known_hosts, which is  the  CA  in  the
       opposite  direction.   This  is  why  it  asks you if you have never connected to a system
       before, it doesn't have the key in its CA.  Or why, if you connect to a  system  you  have
       connected  to  before  and  the  certificates don't match or fail validation, it complains
       about it.

       So if you are using self-signed certificates, you need to be careful to put only ones  you
       trust  in  the  CA.   This is obviously not possible in a large system like the world wide
       web, thus the creation of third-party trusted CAs.

   TRUST AND CRYPTOGRAPHY
       The above discussions mention trust several times.  Cryptography does not remove the  need
       for  trust.  It just makes trust more convenient.  If someone sends you a certificate, you
       need to validate that it was actually them that sent you the certificate, and that it  was
       not  modified  in  transit.   If you add that certificate to your CA, you are trusting the
       certificate, and you better make sure (with fingerprints, generally, see the openssl  docs
       for details) that it came from a trusted entity.

       The  hardest  part  of  cryptography in general is key management.  Breaking cryptographic
       algorithms is really hard.  Getting people to divulge private keys or use the  wrong  keys
       is a lot easier.

       For  more  on cryptography in general, and cryptography and trust, Bruce Schneier has some
       excellent books on the subject.

IPv6, IPV4, and host names

       Note that a single hostname may result in more than one address.   For  instance,  it  may
       have  both an IPv4 and IPv6 address.  These are treated just like multiple hostnames.  The
       hostname may be prefixed with ipv4 or ipv6, which will  force  the  connections  to  those
       protocols.   Specifying  ipv6n4  will  create  a  socket that is IPv6 but will handle IPv4
       connections.  This is the default.

       In general IPv6 addresses are preferred if both are available.

       If you do not specify a hostname on an accepting gensio  (like  sctp,1234)  it  will  only
       create  an IPv6 socket that is IPv4 mapped.  Even though getaddrinfo would normally return
       two addresses, only the IPv6 one is used unless there are  no  IPv6  addresses  configured
       where it will return an IPv4 address.

       In  general,  for  connecting  gensios  only the first address that is found will be used.
       SCTP is the exception, it will do multi-homing on all the addresses that come up.  Do  you
       may need to be fairly specific with addresses.

TCP

       tcp[(<options>)][,<hostname>],<port>[[,<hostname>],<port>[...]]
       hostname = [ipv4|ipv6|ipv6n4,]<name>

       A  TCP  connecting gensio must have the hostname specified.  Mulitiple hostname/port pairs
       may be specified.  For a connecting TCP gensio, each one will be tried in sequence until a
       connection  is established.  For acceptor gensios, every specified hostname/port pair will
       be listened to.

   Dynamic Ports
       For accepters, if the port is specified as zero, a random port in the dynamic  port  range
       specified by IANA will be chosen.  If more than one address is present, the same port will
       be chosen for all addresses.  You  can  fetch  the  port  using  the  gensio_acc_control()
       function with the option GENSIO_ACC_CONTROL_LPORT.

   Out Of Band Data
       TCP  supports out of band (oob) data, which is data that will be delivered out of order as
       soon as possible.  This comes in a normal read, but with "oob" in the  auxdata.   You  can
       send  oob  data by adding "oob" to the write auxdata, but oob writes are limited to 1 byte
       and writing any more than this results in undefined behavior.  Note that "oobtcp" is  also
       delivered and accepted in auxdata, so you can tell TCP oob data from other oob data.

   Options
       In addition to readbuf, the tcp gensio takes the following options:

       nodelay[=true|false]
              Sets nodelay on the socket.

       laddr=<addr>
              An address specification to bind to on the local socket to set the local address.

       reuseaddr[=true|false]
              Set SO_REUSEADDR on the socket, good for accepting gensios only.  Defaults to true.

       tcpd=on|print|off
              Accepter only, sets tcpd handling on the socket.  If "on", tcpd is enforced and the
              connection is just closed on a tcpd denial.  "print" is like on, except  it  writes
              "Access  Denied"  on the socket before closing it.  "off" disabled tcpd handling on
              the socket.  Defaults to on.  Not available if tcpd is disabled at compile time.

       tcpdname=<name>
              Accepter only, sets the name to use for tcpd  access  control.   This  defaults  to
              "gensio", and the default can be overriden with gensio_set_progname().  This option
              allows you to override it on a per-gensio accepter basis.  Not available if tcpd is
              disabled at compile time.

   Remote Address String
       The  remote address will be in the format "[ipv4|ipv6],<addr>,<port>" where the address is
       in numeric format, IPv4, or IPv6.

   Remote Address
       TCP returns a standard struct sockaddr for GENSIO_CONTROL_RADDR_BIN control.

UDP

       udp[(<options>)][,<hostname>],<port>[[,<hostname>],<port>[...]]
       hostname = [ipv4|ipv6|ipv6n4,]<name>

       A UDP gensio creates a UDP socket, but it makes it look  like  an  unrealiable  stream  of
       data.  The specification is the same as a TCP socket, except that a UDP socket is created,
       obviously.

       The semantics of a UDP socket are a little bit strange.  A connecting UDP socket is fairly
       straightforward, it opens a local socket and sends data to the remote socket.

       An  accepter  gensio  is  not  so  straightforward.  The accepter gensio will create a new
       accepted gensio for any packet it receives from a new remote host.  If you disable read on
       any  of  the  accepted gensio or disable accepts on the accepting gensio, it will stop all
       reads on all gensios associated with that accepting gensio.

       Note that UDP accepter gensios are not really required for using UDP,  the  are  primarily
       there  for handling ser2net accepter semantics.  You can create two connecting UDP gensios
       and communicate between them.

       UDP gensios are not reliable, but are obviously packet-oriented.

       Port 0 is supported just like TCP for accepters, see Dynamic  Ports  in  the  TCP  section
       above for details.

       The  destination  address  defaults  to  the  one  specified  on the gensio specifier (for
       connecting gensios) or the remote address that initiated  the  connection  (for  accepting
       gensios), but may be overridden using "addr:<addr>" in the write auxdata.

   Options
       In addition to readbuf, the udp gensio takes the following options:

       laddr=<addr>
              An address specification to bind to on the local socket to set the local address.

       nocon[=true|false]
              Don't  be  connection  oriented,  just receive all packets and deliver them without
              establishing connections.  Only valid for the client gensio.  The  receive  address
              is  passed  into  the auxdata prefixed by "addr:", this is the address formatted by
              gensio_addr_to_str().

       mloop[=true|false]
              If false, multicast packets transmitted will not be received on the local host.  If
              true, they will.

       mttl=[1-255]
              Set the multicast time-to-live value.  The default is 1, meaning multicast stays in
              the local network.  Increasing  this  value  increases  the  number  of  hops  over
              multicast routers a send packet will traverse.

       mcast=<addr>
              Add  an  address to receive multicast packets on.  There is no port number, this is
              just addresses.  You can specify multiple addresses in a  single  multicast  option
              and/or  the  multicast  option can be used multiple times to add multiple multicast
              addresses.

       reuseaddr[=true|false]
              Set SO_REUSEADDR  on  the  socket,  good  for  connecting  and  accepting  gensios.
              Defaults to false.

   Remote Address String
       The  remote address will be in the format "[ipv4|ipv6],<addr>,<port>" where the address is
       in numeric format, IPv4, or IPv6.

   Remote Address
       UDP returns a standard struct sockaddr for GENSIO_CONTROL_RADDR_BIN control.

   UDP Multicast
       Multicast can be used on UDP gensios with the nocon, maddr and laddr options.  To set up a
       multicast,  create  a  client  UDP  gensio  and set the laddr for the receive port and the
       destination address to the multicast and enable nocon, like:

              "udp(mcast='ff02::1',laddr='ipv6,3000',nocon),ff02::1,3000"

       and you will receive and send data on the multicast address.  The laddr option is required
       to  set  the  port  to  receive on.  It means you will have a local address, too, and will
       receive packets on that, too.

SCTP

       sctp[(<options>)][,<hostname>],<port>[[,<hostname>],<port>[...]]
       hostname = [ipv4|ipv6|ipv6n4,]<name>

       An SCTP gensio is specified like a UDP or TCP one.  However, the semantics are  different.
       For  a  connecting  gensio,  it  will attempt to create a multi-homed connect with all the
       specified hostnames and ports.  All the ports must be the same.

       For an accepter gensio, it will create a single socket with all the specified addresses as
       possible destinations.  Again, all the ports must be the same.

       SCTP  gensios  are  reliable.   They  are  not,  at the moment, packet oriented.  There is
       currently no support of SCTP_EXPLICIT_EOR in the Linux implementation of SCTP, and without
       that it would be hard to make it packet oriented.

       When  specifying  IPv6 addresses that might map to IPv4, you must be careful.  If one side
       can do IPv4 and the other side can only do IPv6, the connection  may  come  up,  but  will
       disconnect  quickly  because  it  cannot  communicate on the IPv4 side.  For instance, the
       following accepter:

              tools/gensiot -a "sctp,ipv6,::,1234"

       and the following connector:

              tools/gensiot "sctp,::1,1234"

       will fail this way because the connector will support IPv4 add but the accepter will not.

   Nagle and SCTP
       SCTP implements the Nagle algorithm by default, which can interact badly if  sack_freq  is
       set  to  more  than one.  At least Linux defaults sack_freq to 2, but the gensio overrides
       this to avoid surprising behaviour.  What happens is in some situations  you  can  get  an
       outstanding  packet  that  is  unacked,  since  sack_freq  is greater than one.  The Nagle
       algorithm will not send any new data until any already sent data is acked.  So one end  is
       waiting for a new packet to send a sack, and the other end is holding data until it gets a
       sack.  So you get stuck waiting for the sack_delay where the sack will  go  out  and  kick
       things back off again.

       You need to be aware of this if you modify sack_freq.

   Options
       In addition to readbuf, the sctp gensio takes the following options:

       instreams=<n>

       ostreams=<n>
              These  specify the number of incoming and outgoing streams for the connection.  The
              default is one.  The stream is given in the auxdata  for  read  and  write  in  the
              format "stream=<n>".

       sack_freq=<n>

       sack_delay=<n>
              These  specify  the handling of selective acknowledgements (sacks).  sack_freq sets
              the number of outstanding packets that must be received before sending a sack.  The
              default  is  1,  meaning  it doesn't wait at all.  sack_delay sets the maximum time
              before a sack is sent if outstanding packets are  present,  in  milliseconds.   The
              default  is  10,  but this is disabled if sack_freq is set to 1.  Setting either of
              these to 0 enables the system defaults.

       nodelay[=true|false]
              Sets nodelay on the socket.

       laddr=<addr>
              An address specification to bind to on the local socket to set the local address.

       reuseaddr[=true|false]
              Set SO_REUSEADDR on the socket, good for accepting gensios only.  Defaults to true.

              Port 0 is supported just like TCP for accepters,  see  Dynamic  Ports  in  the  TCP
              section above for details.

              SCTP  support  out  of band (oob) data, which is data that will be delivered out of
              order as soon as possible.  This comes in a normal read,  but  with  "oob"  in  the
              auxdata.  You can send oob data by adding "oob" to the write auxdata.

              See documentation on SCTP for more details.

   Remote Address String
       The         remote        address        will        be        in        the        format
       "[ipv4|ipv6],<addr>,<port>[;[ipv4|ipv6],<addr>,<port>[...]]"   where  the  address  is  in
       numeric format, IPv4, or IPv6.  Each remote address for the SCTP connection is listed.

   Remote Address
       SCTP  returns  a  packed  struct  sockaddr  for GENSIO_CONTROL_RADDR_BIN control, per SCTP
       semantics.

UNIX

       unix[(<options>)],<socket_path>

       Create a unix domain socket as an accepter, or connect  to  a  unix  domain  socket  as  a
       connecter.

       A  file  will be created with the given socket path, you must have permissions to create a
       writeable file in that location.  If the file already exists, an error will be returned on
       an accepter socket unless you specify delsock which will cause the file to be deleted.

       You  should  read  the  unix(7)  man  page  for details on the semantics of these sockets,
       especially permissions.  The options below allow setting various permission and  ownership
       of  the  file,  but  this  may not have any effect on who can open socket depending on the
       particular operating system.  Portable programs should not rely on these  permissions  for
       security.  Also note that Linux remote credentials are not currently implemented.

   Options
       In addition to readbuf, the unix gensio takes the following options:

       delsock[=true|false]
              If the socket path already exists, delete it before opening the socket.

       umode=[0-7|[rwx]*]
              Set   the   user   file  mode  for  the  unix  socket  file.   This  is  the  usual
              read(4)/write(2)/execute(2) bitmask per chmod, but only for the user portion.  If a
              mode  is specified, all other modes default to "6" (rw) +unless they are specified,
              and the final mode is modified by the umask +per standard *nix  semantics.   If  no
              mode  is specified, it is set to +the default and not modified.  Note that the perm
              option below is +probably a better way to set this.

       gmode=[0-7|[rwx]*]
              Set the group file mode for the unix socket file, see umode for details.

       omode=[0-7|[rwx]*]
              Set the other file mode for the uix socket file, see umode for details.

       perm=[0-7][0-7][0-7]
              Set the full mode for the unix socket file per standard *nix semantics, modified by
              umask as the above mode operations are.

       owner=<name>
              Set the owner of the unix socket file to the given user.

       group=<name>
              Set the group of the unix socket file to the given group.

   Remote Address String
       The remote address will be: "unix,<socket path>".

   Remote Address
       UNIX returns a standard struct sockaddr_un for GENSIO_CONTROL_RADDR_BIN control.

serialdev

       serialdev[(<options>)],<device>[,<serialoption>[,<serialoption>]]

       A  serialdev connection is a local serial port.  The device is a /dev/xxx type, and should
       be real stream device of some type that normal termios work on (except for wronly).

       This is, no surprise, a serial gensio.

       One problem with serialdev and UUCP locking is that if you fork() a process while  one  is
       open,  the  forked process will have the serialdev but the value in the UUCP lockfile will
       be incorrect.  There's not much that can be done about this, so be careful.

   Options
       In addition to readbuf, the serialdev gensio takes the following options:

       nouucplock[=true|false]
              disables UUCP locking on the device.  Useful  for  /dev/tty,  which  shouldn't  use
              locking.  This is not available as a default.

       drain_time=off|<time in 100ths of a second>
              The  total  amount  of  time  to wait for the data to be sent on the serial port at
              close time.  Close will be delayed this amount of time, or until all  the  data  is
              transmitted.   Default is off.  When setting the default value for this, "off" will
              not be accepted, use -1 instead.

       char_drain_wait=off|<time in 100ths of a second>
              At close time, if this much time elapses and  no  character  is  sent,  finish  the
              close.  Default is 50 (.5 seconds).  Note that if both this and drain_time are off,
              if the serial port is hung on flow control, it will never close.  When setting  the
              default value for this, "off" will not be accepted, use -1 instead.

       There are a plethora of serialoptions, available as defaults:

       [speed=]<speed><parity><databits><stopbits>
              This  is  a  normal  serial  port configuration specification, like "9600N81".  The
              "speed=" at the beginning is optional, but "speed" is a default type for this.

       wronly[=true|false]
              Set the device to write only.  No termios definition is done on the port.  This can
              be done to talk to a line printer port, for instance.  False by default.

       nobreak[=true|false]
              Clear  the  break  line  at  start (or don't clear it).  Default it to not clear it
              (false).

       rs485=off|<delay rts before send>:<delay rts after send>[:<conf>[:<conf>]]
              Set up RS-485 for the serial port.  The first two parameters set the RTS delay  (in
              milliseconds)   of  RTS  before  and  after  sending.   The  conf  values  can  be:
              "rts_on_send" - RTS set when sending, "rts_after_send" -  RTS  set  after  sending,
              "rx_during_tx"  -  can receive and transmit at the same time, and "terminate_bus" -
              enable bus termination.

              Using "off" will disable rs485;  that  is  useful  for  overriding  a  user-defined
              default setting.  Default is "off".

       xonxoff[=true|false]
              Enable/disable xon/xoff flow control.  Default is false.

       rtscts[=true|false]
              Enable/disable rts/cts flow control.  Default is false.

       local[=true|false]
              Ignore/don't  ignore  the  modem  control lines.  The default it to not ignore them
              (false).  However, if you don't ignore the modem control lines, it  can  result  in
              long shutdown delays.

       dtr[=on|off]
              Force  the DTR line to be on or off when the gensio is opened.  Note that the order
              of the dtr and rts options matter.  Whichever comes first in the  options  will  be
              set first.  This can be useful if the lines need to be sequenced in a certain order
              for the piece of hardware involved.

       rts[=on|off]
              Force the RTS line to be on or off when the gensio is opened.  See the dtr  section
              above for notes on ordering of lines.

       hangup-when-done[=true|false]
              Lower/don't  lower  the modem control lines when the gensio is closed.  The default
              is to not lower the modem control lines on close  (false).   custspeed[=true|false]
              Allow/don't  allow  setting of custom baud rates.  Ignored if custom baud rates are
              not supported.  Normally only standard baud rates are supported (1200, 2400,  etc).
              If supported by the hardware, this allows any arbitrary value to be set.

   Remote Address String
       The   remote   address   string  is  the  device  and  serial  parms,  in  a  format  like
       "9600N81[,<option>[,<option>[...]]]".   Options  are  one  of:  XONXOFF,  RTSCTS,  CLOCAL,
       HANGUP_WHEN_DONE, RTSHI, RTSLO, DTRHI, DRLO, offline.

   Remote ID
       The remote ID for the serial dev is the file descriptor returned as an integer.

stdio

       accepter = stdio[(options)]
       connecting = stdio[(options)],<program>

       The stdio gensio is a fairly strange one, but it's fairly useful.

       A  connecting  stdio  gensio  runs the given program (unless self is set as an option) and
       connects its standard input and output to the gensio's main channel.  So it's easy to  run
       a program and interact with it.  If you want to get stderr from the gensio, open a channel
       on the main channel gensio, see below.

       NOTE: Though epoll() doesn't work with normal files, the stdio gensio has special handling
       for  normal  files  so they mostly work.  This can have surprising side effects if you use
       stdin as a normal file.  When you hit the end of  stdin,  the  stdio  gensio  will  return
       GE_REMCLOSE and you may shut down the gensio and possibly lose any output going to stdout.
       Use the file gensio if you can.

       For connecting gensios, in the forked process, the code will set the uid and guid  to  the
       current set effective uid and guid if the effective and real uids are different.  This way
       a user can set the effective uid and gid to what they want the program to run  under,  but
       keep the uid and gid to the (probably root) values so they can be restored to those values
       after opening the pty.  The group list is also set to the groups the effective  userid  is
       in.  Note that nothing is done if the effective and real userids are the same.

       If you have both stdin/stdout and stderr opened, you must close both of them to completely
       close the gensio.  You cannot re-open the gensio until both are closed.

       The  connecting  gensio  support  the  GENSIO_CONTROL_ENVIRONMENT  control  to  allow  the
       environment to be set for the new process.

       An  accepting  gensio  immediately does a connection when started and connection stdin and
       stdout of the running program to the gensio.

   Options
       In addition to readbuf, a connecting stdio takes the following options:

       self[=true|false]
              Instead of starting a program, connect to the running program's stdio.  This is the
              same  as  an accepting stdio gensio, except you don't have to go through the accept
              process.

       console[=true|false]
              Like self, except connect to the running program's console device, /dev/tty on Unix
              and CONIN$/CONOUT$ on Windows.  Useful for reading passwords and such.

       raw[=true|false]
              For  a  "self",  console,  or  accepter version of the gensio, put the I/O in "raw"
              mode, meaning character at a time, turn off ^C, etc.  This will fail  on  pipes  or
              files.

       stderr-to-stdout
              Send standard error output to standard out instead of having a separate channel for
              it.

       noredir-stderr
              Do not modify the stderr for the program, use the calling program's  stderr.   This
              can be useful if you want to see stderr output from a program.

   Channels
       The  stdio connecting gensio that start another program does not provide stderr as part of
       the main gensio. You must create a channel with gensio_alloc_channnel() and then  open  it
       get stderr output.  The args for gensio_alloc_channel() may be an optional "readbuf=<num>"
       and sets the size of the input buffer.

   Remote Address String
       The remote address string is either "stdio,<args>" for the main channel or "stderr,<args>"
       for the error channel.  The args will be a set of quoted strings with a space between each
       string, one for each argument, with '"' around each  argument,  each  '"'  in  the  string
       converted to '\"' and each '\' in the string converted to '\\'.

   Remote ID
       The  remote  ID is the pid for the remote device, only for connecting gensios that start a
       program, not for any other type.

echo

       connecting = echo[(options)]

       The echo gensio just echos back all the data written to it.  Useful for testing.

   Options
       In addition to readbuf, a connecting echo takes the following options:

       noecho[=true|false]
              Instead of echoing the data, just become a data sink.

   Remote Address String
       The remote address string is "echo".

file

       connecting = file[(options)]

       The file gensio opens an (optional) input file and (optional) output file for the  gensio.
       If  you  need  to  read/write a file in gensio, you must use this.  Semantics on files for
       stdio do not alway work correctly.

       If an input file is specified, data will be read from the input file and delivered on  the
       read  interface  of  the  gensio  until  end  of  file, when the GE_REMCLOSE error will be
       returned.

       If an output file is specified, data will be written to the output file  on  writes.   The
       output file is always ready to receive data.

   Options
       In addition to readbuf, a connecting file takes the following options:

       infile=filename
              Set the input filename.

       outfile=filename
              Set the output filename.

       read_close[=true|false]
              If  this is true (the default), cause a GE_REMCLOSE error on read when all the file
              data is ready.  If false, just stop returning data and don't  do  the  GE_REMCLOSE.
              This is useful if you just want to inject a bunch of data then do nothing.

       create[=true|false]
              Create the output file if it does not exist.

       umode=[0-7|[rwx]*]
              Set  the  user  file  mode  for the file if the file is created.  This is the usual
              read(4)/write(2)/execute(2) bitmask per chmod, but only for the user portion.  If a
              mode  is specified, all other modes default to "6" (rw) +unless they are specified,
              and the final mode is modified by the umask +per standard *nix  semantics.   If  no
              mode  is specified, it is set to +the default and not modified.  Note that the perm
              option below is +probably a better way to set this.

       gmode=[0-7|[rwx]*]
              Set the group file mode for the file if the file is created, see umode for details.

       omode=[0-7|[rwx]*]
              Set the other file mode for the file if the file is created, see umode for details.

       perm=[0-7][0-7][0-7]
              Set the full mode for the file per standard *nix semantics, modified  by  umask  as
              the above mode operations are.

   Remote Address String
       The remote address string is "file([infile=<filename][,][outfile=<filename>])".

dummy

       accepter = dummy

       The dummy gensio accepter is useful for place holding, where you don't want a real working
       accepter but need to put something.

       As you might guess, it doesn't do anything.

ipmisol

       ipmisol[(options)],<openipmi arguments>[,ipmisol option[,...]]

       An ipmisol gensio creates an IPMI Serial Over LAN connection to an IPMI server.   See  the
       OpenIPMI documentation for information on the arguments.

       This is a serial gensio, but the baud rate settings are fairly limited.

   Options
       In addition to readbuf, the ipmisol gensio takes the following options:

       writebuf=<n>
              to set the size of the write buffer.

       It also takes the following ipmisol options:

       9600, 19200, 38400, 57600, 115200
              Baud   rate,   9600  by  default.   Anything  after  the  number  is  ignored,  for
              compatibility with things like "N81".  You cannot set  those  values  for  ipmisol,
              they are fixed at "N81".

       nobreak[=true|false]
              Disable break processing.  False by default.

       authenticated[=true|false]
              Enable or disable authentication.  True by default.

       encrypted[=true|false]
              Enable or disable encrypted.  True by default.

       deassert-CTS-DCD-DSR-on-connect[=true|false]
              False by default

       shared-serial-alert=fail|deferred|succeed
              Behavior of handling serial alerts.  fail by default.

       ack-timeout=<number>
              The time (in microseconds) when an ack times out.  1000000 by default.

       ack-retries=<number>
              The  number  of  times  (ack-timeouts)  an  ack is re-sent before giving up.  10 by
              default.

telnet

       accepter = telnet[(options)]
       connecting = telnet[(options)]

       A telnet gensio is a filter that sits on top of another  gensio.   It  runs  the  standard
       telnet protocol andn support RFC2217.

   Options
       In addition to readbuf, the telnet gensio takes the following options:

       writebuf=<n>
              set the size of the write buffer.

       rfc2217[=true|false]
              enable  or disable RFC2217 mode for this gensio.  If this is enabled and the remote
              end of the connection supports RFC2217 also, the gensio will be set up as a  serial
              gensio and you can do normal serial gensio handling on it.

       mode=client|server
              Set  the  telnet  mode to client or server.  This lets you run a telnet server on a
              connecting gensio, or a telnet client on an accepter gensio.

   Remote info
       telnet passes remote id, remote address, and remote string to the child gensio.

ssl

       accepter = ssl[(options)]
       connecting = ssl[(options)]

       An SSL gensio runs the SSL/TLS protocol on top of another gensio.   That  gensio  must  be
       reliable.

       Use  is  pretty  straightforward.   The  hardest  part  about  using the SSL gensio is the
       certificates.  A server SSL gensio must be given a certificate and a key.   A  client  SSL
       gensio  must  be  given  a  certificate  authority.   A  client  will user the certificate
       authority to verify that the server has the proper certificate and keys.

       The gensio has options to have the server request the  certificate  from  the  client  and
       validate it.

       SSL gensios are reliable.  They are also packet-oriented.

   Options
       In addition to readbuf, the SSL gensio takes the following options:

       writebuf=<n>
              set the size of the write buffer.

       CA=<filepath>
              Set  a  place  to  look for certificates for authorization.  If this ends in a "/",
              then this is expected to be a directory that contains files with certificates  that
              must  be  hashed  per  OpenSSL  (see  the  "openssl  rehash"  command  for details.
              Otherwise it is a single file that contains one or more certificates.  The  default
              CA  path  is  used  if  not  specified.   Note that setting this to an empty string
              disables it, so you can override a default value if necessary.

       key=<filename>
              Specify the file to get the private key for  the  server.   This  is  required  for
              servers.   It  may  be specified for clients, and is required for the client if the
              server requires a certificate (it has CA set).

       cert=<filename>
              Specify the file that contains the certificate used for the connection.  If this is
              not  specified,  the  certificate  is  expected  to  be in the key file.  Note that
              setting this to an empty string disables it, so you can override a default value if
              necessary.

       mode=client|server
              Normally  an accepter gensio is in server mode and a connecting gensio is in client
              mode.  This can be used to switch the roles  and  run  in  SSL  server  mode  on  a
              connecting gensio, or vice versa.

       clientauth[=true|false]
              Normally  a  client is not authorized by the server.  This requires that the client
              provide a certificate and authorizes that certificate.  Ignored for client mode.

       allow-authfail[=true|false]
              Normally if the remote end certificate is not valid, the SSL gensio will close  the
              connection.   This  open  allows  the  open  to  succeed with an invalid or missing
              certificate.  Note that the user should verify that  authentication  is  set  using
              gensio_is_authenticated().

              Verification  of  the  common name is not done.  The application should do this, it
              can fetch the common name and other certificate data through a control interface.

              You can use self-signed certificates in this  interface.   Just  be  aware  of  the
              security  ramifications.   This  gensio  is  fairly  flexible,  but you must use it
              carefully to have a secure interface.

              The SSL gensio will call the gensio event callback (client) or the gensio  acceptor
              event  callback  (server)  after  the  certificate  is  received  but  before it is
              validated with the GENSIO_EVENT_PRECERT_VERIFY  or  GENSIO_ACC_EVENT_PRECERT_VERIFY
              events.   This  allows  the user to validate data from the certificate (like common
              name) with GENSIO_CONTROL_GET_PEER_CERT_NAME or set a certificate authority for the
              validation with GENSIO_CONTROL_CERT_AUTH.

   Remote info
       ssl passes remote id, remote address, and remote string to the child gensio.

certauth

       accepter = certauth[(options)]
       connecting = certauth[(options)]

       A  certauth  gensio  runs  an  authentication  protocol to on top of another gensio.  That
       gensio must be reliable and encrypted.

       This is like the reverse of SSL.  The client has a key and certificate, the server  has  a
       certificate authority (CA).  This also supports password authentication.

       Once  authentication occurs, this gensio acts as a passthrough.  The readbuf option is not
       available in the gensio.

   Options
       The certauth gensio takes the following options:

       CA=<filepath>
              Set a place to look for certificates for authorization.  If this  ends  in  a  "/",
              then  this is expected to be a directory that contains files with certificates that
              must be hashed per OpenSSL, see the gensio-keygen(1)  in  the  rehash  section  for
              details.   Otherwise  it  is  a single file that contains one or more certificates.
              The default CA path for openssl is used if not specified.   This  is  used  on  the
              server  only,  it is ignored on clients.  Note that setting this to an empty string
              disables it, so you can override a default value if necessary.

       key=<filename>
              Specify the file to get the private key for  the  client.   This  is  required  for
              clients.  It is ignored on server.

       cert=<filename>
              Specify  the  file  to  get  the  private key for the client.  This is required for
              clients.  It is ignored on server.  If this is not specified,  the  certificate  is
              expected to be in the key file.  Note that setting this to an empty string disables
              it, so you can override a default value if necessary.

       username=<name>
              Specify a username to authenticate with on the remote end.  This  is  required  for
              the client.  It is ignored on the server.

       service=<string>
              Set  the  remote  service requested by the client.  Optional, but the other end may
              reject the connection if it is not supplied. Ignored on the server.

       password=<string>
              Specify the password to use for password authentication.  This is not  recommended,
              the callback is more secure to use.

       mode=client|server
              Normally  an accepter gensio is in server mode and a connecting gensio is in client
              mode.  This can be used to switch the roles and run in server mode on a  connecting
              gensio, or vice versa.

       allow-authfail[=true|false]
              Normally if the remote end certificate is not valid, the certauth gensio will close
              the connection.  This open allows the open to succeed with an  invalid  or  missing
              certificate.   Note  that  the  user should verify that authentication is set using
              gensio_is_authenticated().

       use-child-auth[=true|false]
              If the child gensio is authenticated,  then  do  not  run  the  protocol,  just  go
              straight into passthrough mode and don't do any authentication.

       enable-password[=true|false]
              On  the server, allow passwords for login.  On the client, send a password if asked
              for one.  By default passwords are disabled.  Use of passwords is much less  secure
              than certificates, so this is discouraged.

       enable-2fa[=true|false]
              On  the server, request 2-factor authentication data from the client.  This is only
              useful for situations where the 2-factor data is known before startup, like  Google
              Authenticator  or  other  things  of  that nature.  It is not useful for text/email
              types of things that send the data after the connection is  initiated.   But  those
              are usually interactive and can be handled with interactive methods.

       2fa=<string>
              On  the  client, provide the given 2-factor authentication data to the server if it
              asks for it.

       Verification of the common name is not done.  The application should do this, it can fetch
       the  common  name and other certificate data through a control interface.  It may also use
       the username fetched through the control interface.

       You can use self-signed certificates in this interface.  Just be  aware  of  the  security
       ramifications.   This  gensio  is  fairly  flexible, but you must use it carefully to have
       secure authentication.

       The certauth gensio has 4 major callbacks dealing with authentication of the  user.   They
       may or may not be called depending on the circumstances.  The normal events come in if you
       have allocated a gensio and are doing an open.  The _ACC_ events come in if it  is  coming
       in  from an accept and there is no gensio reported yet.  In the _ACC_ case, be careful, do
       not use the given gensio for anything but checking certificate  and  username  parameters,
       and do not save it.

       All  these  calls  should return 0 if they want the authentication to immediately succeed,
       EKEYREJECTED if they reject the authentication, ENOTSUP if they want  certauth  to  ignore
       that  part  of  the  authentication, or any other errno will result in the connetion being
       shut down.

       The callbacks are:

       GENSIO_EVENT_AUTH_BEGIN / GENSIO_ACC_EVENT_AUTH_BEGIN
              On the server side, this is called when to  authentication  is  requested  buy  the
              client.    The   username   will   be   available  if  the  user  provided  it  via
              GENSIO_CONTROL_USERNAME.

       GENSIO_EVENT_PRECERT_VERIFY / GENSIO_ACC_EVENT_PRECERT_VERIFY
              On the server side, thi is called after  the  certificate  has  been  received  but
              before  it  is verified.  The user can use this to query the certificate and update
              the certificate authority based on username or certificate information.

       GENSIO_EVENT_VERIFY_PASSWORD / GENSIO_ACC_EVENT_VERIFY_PASSWORD
              On the server side, this is called if the certificate verification has  failed  and
              after  the password has been requested from the remote end.  The password is passed
              in, it is cleared immediately after this call.

       GENSIO_EVENT_REQUEST_PASSWORD / GENSIO_ACC_EVENT_REQUEST_PASSWORD
              On the client side, this is called if the server requests that a password  be  sent
              and  the  password  is  not  already set for the gensio.  The requested password is
              immediately cleared after being sent to the server.

   Remote info
       certauth passes remote id, remote address, and remote string to the child gensio.

mux

       accepter = mux[(options)]
       connecting = mux[(options)]

       A mux gensio is a gensio filter that allows one or more channels to be created on top of a
       single  gensio,  multiplexing  the  connection.   Each  channel  has full individual flow-
       control.  The channels are message oriented as described above, and  use  can  use  a  mux
       without  additional  channels  to  just do message demarcation.  They also support out-of-
       bounds messages.

   Options
       A mux gensio takes the following options:

       max_channels=<n>
              Allow at most <n> channels to be created in the mux.  The  default  is  1000.   The
              minimum value of <n> is 1, the maximum is 65536.

       service=<string>
              Set  the  remote  service requested by the client.  Optional, but the other end may
              reject the connection if it is not supplied. Ignored on the server.

       mode=client|server
              By default a mux accepter is a server  and  a  mux  connecter  is  a  client.   The
              protocol  is  mostly  symmetric,  but it's hard to kick things off properly if both
              sides try to start things.  This option lets you override the default mode in  case
              you have some special need to do so.

       When  the  open is complete on the mux gensio, it will work just like a transparent filter
       with message demarcation.  In effect, you have one channel open.

   Creating Channels
       To create a channel, call the gensio_alloc_channel() function on  the  mux  gensio.   This
       will  return a new gensio that is a channel on the mux gensio.  You can pass in arguments,
       which is an array of strings, currently readbuf, writebuf, and service are accepted.   The
       service you set here will be set on the remote channel so the other end can fetch it.  The
       new channel needs to be opened with gensio_open() before it can be used.

       As you might imaging, the other end of a mux needs to know about the new channel.  If  one
       end  (either  end,  doesn't  matter)  calls  gensio_alloc_channel() and then opens the new
       channel, the other end will get a  GENSIO_EVENT_NEW_CHANNEL  event  as  described  in  the
       Streams  and  Channels section.  You can call it using any mux channel.  The first element
       in the auxdata is the service.

       You can modify the service value after you allocate the channel but before you open it.

   Out Of Band Messages
       mux support out of band (oob) data, which is data that will be delivered  normally.   This
       comes  in  a  normal read, but with "oob" in the auxdata.  You can send oob data by adding
       "oob" to the write auxdata.  You should normally use the "eom" flag so the end of the  out
       of band messages ismarked.

       This is so you can send special data outside of the normal processing of data.

   Mux Events
       As  you  might  imaging,  normal  data  events  come  through  the gensio channel they are
       associated with.  Close events will, too.  If a mux gensio  closes  abnormally  (like  the
       underlying connection fails) you will get a read error on each channel.

       New  channel  events  (and  other global events coming from lower gensios, like if you are
       running over ssl or telnet) come in through the original gensio  normally.   However,  you
       can  close  that, another channel will be chosen to receive those event.  In general, it's
       best to handle the global events on all channels and not assume.

   Closing and Freeing a Mux
       To close a mux gensio, just close all channels associated with it.   There  is  no  global
       close  mechanism (you would not believe the complexity that adds).  Once you have closed a
       mux gensio, you can re-open it with gensio_open().  It will not recreate all the  channels
       for  you,  you  will  have one channel, and the channel you use to call gensio_open() will
       become the first channel.

       You cannot re-open individual channels.

       To free a mux gensio, you must free all the channels on it.

pty

       connecting = pty[(options)][,<program>]

       Create a pty and optionally run a program  on  the  other  end  of  it.   With  a  program
       specified,  this  is  sort  of like stdio, but the program is running on a terminal.  Only
       connection gensios are supported.

       pty has some unusual handling to allow execution of login shells of users from root.

       If the first character of the program is '-', it is removed  from  the  execution  of  the
       command but left in argv[0].  This will cause a shell to act as a login shell.

       In the forked process, the pty code will set the uid and guid to the current set effective
       uid and guid if the effective and real uids are different.  This way a user  can  set  the
       effective  uid and gid to what the want to pty to run under, but keep the real uid and gid
       to the (probably root) values so they can be restored to those values  after  opening  the
       pty.   The  group  list  is  also set to the groups the effective userid is in.  Note that
       nothing is done if the effective and real userids are the same.

       The pty gensio supports the GENSIO_CONTROL_ENVIRONMENT control to allow the environment to
       be set for the new process.

       If  no program is specified, when the pty gensio is opened it will just create the pty but
       won't attach anything to it.  Another program can open the pty.  You can get the slave pty
       device by getting the local address string.

   Options
       In  addition  to  readbuf,  the pty gensio takes the following options.  These options are
       only allowed if the pty is unattached.  ptys with programs run on them need to follow  the
       standard semantics.

       link=<filename>
              create  a  symbolic  link  from  filename to the pty name.  This way you can have a
              fixed reference  to  refer  to  the  pty.   Standard  permissions  apply.   Without
              forcelink the open will file if filename already exists.

       forcelink[=true|false]
              if  link is specified, if a file already exists where the symbolic link is, replace
              it.  Be careful, it deletes whatever is there indiscriminately.

       raw[=true|false]
              causes the pty to be set in raw mode at startup.  This is  important  for  anything
              that  will  start writing immediately to the pty.  If you don't set this, echo will
              be on and writes on the master will be echoed back.  In general, this is useful for
              unattached ptys.  It was added for testing, but will be usedful in many situations.

       umode=[0-7|[rwx]*]
              Set   the   user   file   mode   for   the   pty   slave.    This   is   the  usual
              read(4)/write(2)/execute(2) bitmask per chmod, but only for the user portion.  If a
              mode  is specified, all other modes default to "6" (rw) +unless they are specified,
              and the final mode is modified by the umask +per standard *nix  semantics.   If  no
              mode  is specified, it is set to +the default and not modified.  Note that the perm
              option below is +probably a better way to set this.

       gmode=[0-7|[rwx]*]
              Set the group file mode for the pty slave, see umode for details.

       omode=[0-7|[rwx]*]
              Set the other file mode for the pty slave, see umode for details.

       perm=[0-7][0-7][0-7]
              Set the full mode for the pty per standard *nix semantics, modified by umask as the
              above mode operations are.

       owner=<name>
              Set the owner of the slave pty to the given user.

       group=<name>
              Set the group of the slave pty to the given group.

   Remote Address String
       The  remote  address string the program and arguments run on the pty.  The argiuments will
       be a set of quoted strings with a space between each string, one for each  argument,  with
       '"'  around  each  argument,  each '"' in the string converted to '\"' and each '\' in the
       string converted to '\\'.

   Remote Address
       The address is a pointer to an integer, the ptym file  descriptor  is  returned.   addrlen
       must be set to sizeof(int) when passed in.

   Local Address String
       This  returns  the  device  of  the  pty,  generally /dev/pts/<n>.  This is useful for pty
       gensios with no program, it allows you to get the value for the other end to  connect  to.
       Note  that  if  you  close  and re-open a pty gensio, you may be a different local address
       string.

msgdelim

       accepter = msgdelim[(options)]
       connecting = msgdelim[(options)]

       A message delimiter converts an unreliable stream (like a serial port) into an  unreliable
       packet  interface.   This is primarily to allow a reliable packet interface like relpkt to
       run on top of a serial port.  It does not support streaming of  data,  so  it's  not  very
       useful by itself.

       Messages  are delimited with a start of message and end of message and have a CRC16 on the
       end of them.

       This is primarily for use on serial ports and other streams that can munge  up  the  data.
       Use the mux gensio for TCP and such.

       THe  default  buffer  size  is  128  bytes,  which is ok for a reasonably fast serial port
       interface.

   Options
       In addition to readbuf, the msgdelim gensio takes the following options:

       writebuf=<n>
              set the size of the write buffer.

       crc[=on|off]
              Enable/disable the CRC at the end of the packet.  Useful if you are running over  a
              reliable  protocol, and especially for testing relpkt so you can fuzz it and bypass
              the crc errors.

relpkt

       accepter = relpkt[(options)]
       connecting = relpkt[(options)]

       Converts an unreliable packet interface (currently only UDP and msgdelim) into a  reliable
       packet  interface.   This  lets  you  have  a reliable connection over a serial port (with
       msgdelim) or UDP.

       Note that UDP is not recommended, it doesn't handle flow control and such  in  a  friendly
       manner.

       relpkt is unusual in dealing with clients and servers.  The protocol is symmetric, for the
       most part, you can start two clients and they will connect to  each  other,  if  they  are
       started  relatively  close  in  time to avoid one timing out.  A relpkt server will simply
       wait forever for an incoming connection on an open.

       relpkt does not support readbuf.  It supports the following:

       max_pktsize=<n>
              Sets the maximum size of a packet.  This may be reduced by the remote end, but will
              never  be  exceeded.  This must be at least 5 bytes shorter than the maximum packet
              size of the interface below it.  This defaults to 123 (msgdelim max packet  size  -
              5).  If run over UDP, this should probably be increased for performance.

       max_packets=<n>
              Sets  the maximum number of outstanding packets.  This may be reduced by the remote
              end, but will never be exceeded.

       mode=client|server
              By default a relpkt is a server on an accepter and a client on  a  connecter.   See
              the discussion above on clients and servers.

trace

       accepter = trace[(options)]
       connecting = trace[(options)]

       A transparent gensio that allows the data passing through it to be sent to a file.  Useful
       for debugging.  It can also block data in either direction.

       Note that the trace gensio only prints data that is accepted by the other  end.   So,  for
       instance,  if  the  trace  gensio  receives  100  bytes  of  read data, it will deliver it
       immediately to the gensio above it.  If that only accepts 40 bytes, trace will only  print
       40 bytes and will only accept 40 bytes from the gensio below it.  Same for sent data.

   Options
       trace does not support readbuf.  It supports the following options:

       dir=none|read|write|both
              Sets  what  data  is  traced.  "none" means no data is traced (the default), "read"
              traces data flowing up the gensio stack (read by the  parent),  write  traces  data
              flowing  down the gensio stack (written by the parent), and "both" traces reads and
              writes.

       block=none|read|write|both
              Blocks data in one or both directions.  "none" means  data  flows  both  directions
              (the  default),  "read"  means data flowing up the gensio stack is discarded, write
              means data flowing down the gensio stack is discarded,  and  "both"  discards  both
              reads and writes.  Data that is discarded is not traced.

       raw[=yes|no]
              If  set, traced data will be written as raw bytes.  If not set, traced data will be
              written in human-readable form.

       file=<filename>
              The filename to write trace data to.  If not supplied, tracing is  disabled.   Note
              that  unless  delold  is  specified,  the file is opened append, so it will add new
              trace data onto the end of an existing file.

       stderr[=yes|no]
              Send the trace output to standard error.  Overrides file.

       stdout[=yes|no]
              Send the trace output to standard output.  Overrides file and stderr.

       delold[=yes|no]
              Delete the old data in the file instead of appending to the file.

perf

       accepter = perf[(options)]
       connecting = perf[(options)]

       A gensio for measuring throughput for a connection.  This  allows  the  performance  of  a
       connection  to  be  measured.   It does not pass any data through.  Instead, it writes raw
       data to the lower layer (if write_len is  set)  and  reads  data  from  the  lower  layer,
       counting the bytes and measuring the time.

       To the upper layer, perf prints out statistics about the data transfer.  It prints out the
       number of bytes written and read each second, and at the end it prints a total.

       If write_len and/or expect_len is non-zero, then the filter will return  GE_REMCLOSE  when
       it  runs  out  of  write  data  and has received all expected data.  If both are zero, the
       connection will not be closed by the gensio.

   Options
       perf does not support readbuf.  It supports the following options:

       writebuf=<n>
              Sets the size of the buffer to write to the child gensio.  Each write will be  this
              size.  This defaults to zero.

       write_len=<n>
              The number of bytes to write.

       expect_len=<n>
              The number of bytes to expect from the other end.

conacc

       accepter = conacc,<gensio string>

       conacc is a gensio accepter that takes a gensio as a child.  When the accepter is started,
       it opens the child gensio.  When the child gensio finishes the  open,  it  reports  a  new
       child for the accepter.  The reported gensio can be used normally.

       When  the  gensio is closed, when the close completes the accepter will attempt to re-open
       the gensio.  This means that if the gensio has some sort of random address (like a pty  or
       a tcp address with the port set to zero) you can get a different address for the re-opened
       gensio.  So you must refetch the local address or local port in this case.

mdns

       connecting = mdns[(options)][,<name>]

       This gensio uses mDNS to find a service and then attempts to connect to it.  This  can  be
       convenient,  it  finds  the connection type andport for you, automatically adds telnet and
       rfc2217 if it's available.  The mDNS name can be set as an option or as the  string  after
       the comma show above.

   Options
       The  readbuf  option is accepted, but if it is not specified the default value for readbuf
       will be taken for the sub-gensio is taken.  In addition to readbuf, the mdns gensio  takes
       the following options:

       nostack[=true|false]
              By  default  the mdns gensio will attempt to use the "gensiostack" text string from
              the mDNS service.  If you don't want it to do this, setting this option  will  turn
              it off.

       name=<mdnsstr>
              Set  the  mdns  name  to search for.  You generally want to set this, otherwise you
              will get the first thing that comes up from the search.

       type=<mdnsstr>
              Set the mdns type to search for.

       domain=<mdnsstr>
              Set the mdns domain to search for.  You generally don't use this.

       host=<mdnsstr>
              Set the mdns host to search for.  You generally don't use this.

       interface=<num>
              Set the network interface number to search on.  The default is -1, which means  all
              interfaces.

       nettype=unspec|ipv4|ipv6
              The network type to search for.  unspec means any type, otherwise you can choose to
              limit it to ipv4 and ipv6.

       nodelay[=true|false]
              Sets nodelay on the socket.  This will be ignored for udp.  Note that  the  default
              value  for mdns is ignored, if you don't set it here it will take the default value
              for the sub-gensio that gets chosen.  laddr=<addr> An address specification to bind
              to on the local socket to set the local address.

       Forking and gensios
              Unlike  normal  file  descriptors,  when  you  fork with a gensio, you now have two
              unassociated copies of the gensios.  So if you do operations on one, it might  mess
              up  the other.  Even a close might cause issues, if you close an SSL connection, it
              sends data to the other end to close the connection, even if the other fork doesn't
              want that.

              To  avoid  issues with this, you should generally first make sure that no thread is
              in a wait, service call, or any type of thing that would examine  file  descriptors
              or  timers  and act on them.  This is very important, and you must do it before you
              fork.

              Then after you fork, you should call:

              gensio_disable(io)

       on all the gensios that fork is not using, then free the gensios.  Don't  use  close,  use
       free.  Then you should call:

              gensio_acc_disable(acc)

       on  every  gensio  accepter that fork is not using, then free them.  If a connection is in
       progress and has not been reported to the user, it will be disabled then closed.

       You cannot share a gensio between two different processes.  If a gensio  is  used  in  one
       fork, it must be disabled and closed in the other fork.

       Another  issue  with  forking on Linux is epoll.  An epoll fd is not duplicated on a fork,
       both forks get the same epoll fd.  If you close the epoll fd in one for, it will close  it
       for  the other.  To avoid this issue, the os handler has a handle_fork() function that you
       must call after a fork in the new fork (not the old one).   It  will  handle  any  cleanup
       required  after  the  fork.  Other systems may require other cleanups after a fork, so you
       should always call this after a fork.

SEE ALSO

       gensiot(1), sctp(7), udp(7), tcp(7), unix(7)

KNOWN PROBLEMS

       None.

AUTHOR

       Corey Minyard <minyard@acm.org>