summaryrefslogtreecommitdiffstats
path: root/src/vnet/dhcp
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2019-08-29 18:33:24 -0700
committerFlorin Coras <florin.coras@gmail.com>2019-08-30 02:16:19 +0000
commita495a3ea146a8484dac9f6b594fb2b044437c7a4 (patch)
tree56c56d95dd80f84944f87cbee12e5c7da0740dfe /src/vnet/dhcp
parentfcd5e12b1c879b27d9ed53c9c5b3ae98b0a04ccf (diff)
tcp: track zero rwnd errors
Type: feature Distinguish between rcv window errors and errors after we advertised a zero rcv window, i.e., potential window probes. Change-Id: I6cb453c7aaae456c0a05a8328cfaa55eaca10bf7 Signed-off-by: Florin Coras <fcoras@cisco.com>
Diffstat (limited to 'src/vnet/dhcp')
0 files changed, 0 insertions, 0 deletions
pf { color: #75715e } /* Comment.PreprocFile */ .highlight .c1 { color: #75715e } /* Comment.Single */ .highlight .cs { color: #75715e } /* Comment.Special */ .highlight .gd { color: #f92672 } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gi { color: #a6e22e } /* Generic.Inserted */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #75715e } /* Generic.Subheading */ .highlight .kc { color: #66d9ef } /* Keyword.Constant */ .highlight .kd { color: #66d9ef } /* Keyword.Declaration */ .highlight .kn { color: #f92672 } /* Keyword.Namespace */ .highlight .kp { color: #66d9ef } /* Keyword.Pseudo */ .highlight .kr { color: #66d9ef } /* Keyword.Reserved */ .highlight .kt { color: #66d9ef } /* Keyword.Type */ .highlight .ld { color: #e6db74 } /* Literal.Date */ .highlight .m { color: #ae81ff } /* Literal.Number */ .highlight .s { color: #e6db74 } /* Literal.String */ .highlight .na { color: #a6e22e } /* Name.Attribute */ .highlight .nb { color: #f8f8f2 } /* Name.Builtin */ .highlight .nc { color: #a6e22e } /* Name.Class */ .highlight .no { color: #66d9ef } /* Name.Constant */ .highlight .nd { color: #a6e22e } /* Name.Decorator */ .highlight .ni { color: #f8f8f2 } /* Name.Entity */ .highlight .ne { color: #a6e22e } /* Name.Exception */ .highlight .nf { color: #a6e22e } /* Name.Function */ .highlight .nl { color: #f8f8f2 } /* Name.Label */ .highlight .nn { color: #f8f8f2 } /* Name.Namespace */ .highlight .nx { color: #a6e22e } /* Name.Other */ .highlight .py { color: #f8f8f2 } /* Name.Property */ .highlight .nt { color: #f92672 } /* Name.Tag */ .highlight .nv { color: #f8f8f2 } /* Name.Variable */ .highlight .ow { color: #f92672 } /* Operator.Word */ .highlight .w { color: #f8f8f2 } /* Text.Whitespace */ .highlight .mb { color: #ae81ff } /* Literal.Number.Bin */ .highlight .mf { color: #ae81ff } /* Literal.Number.Float */ .highlight .mh { color: #ae81ff } /* Literal.Number.Hex */ .highlight .mi { color: #ae81ff } /* Literal.Number.Integer */ .highlight .mo { color: #ae81ff } /* Literal.Number.Oct */ .highlight .sa { color: #e6db74 } /* Literal.String.Affix */ .highlight .sb { color: #e6db74 } /* Literal.String.Backtick */ .highlight .sc { color: #e6db74 } /* Literal.String.Char */ .highlight .dl { color: #e6db74 } /* Literal.String.Delimiter */ .highlight .sd { color: #e6db74 } /* Literal.String.Doc */ .highlight .s2 { color: #e6db74 } /* Literal.String.Double */ .highlight .se { color: #ae81ff } /* Literal.String.Escape */ .highlight .sh { color: #e6db74 } /* Literal.String.Heredoc */ .highlight .si { color: #e6db74 } /* Literal.String.Interpol */ .highlight .sx { color: #e6db74 } /* Literal.String.Other */ .highlight .sr { color: #e6db74 } /* Literal.String.Regex */ .highlight .s1 { color: #e6db74 } /* Literal.String.Single */ .highlight .ss { color: #e6db74 } /* Literal.String.Symbol */ .highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #a6e22e } /* Name.Function.Magic */ .highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */ .highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */ .highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */ .highlight .vm { color: #f8f8f2 } /* Name.Variable.Magic */ .highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */ } @media (prefers-color-scheme: light) { .highlight .hll { background-color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ }
.. _quic_plugin:
.. _quicly: https://github.com/h2o/quicly

.. toctree::

QUIC HostStack
==============

The quic plugin provides an `IETF QUIC protocol <https://tools.ietf.org/html/draft-ietf-quic-transport-22>`_ implementation. It is based on
the quicly_ library.

This plugin adds the QUIC protocol to VPP's Host Stack. As a result QUIC is
usable both in internal VPP applications and in external apps.

**Maturity**

- This plugin is under current development: it should mostly work, but has not been thoroughly tested and should not be used in production.
- Only bidirectional streams are supported currently.

Getting started
---------------

* A common sample setup is with two vpp instances interconnected #twovppinstances
* Ensure your vpp configuration file contains ``session { evt_qs_memfd_seg }``
* Then run ``session enable`` in the debug cli (vppctl)

This plugin can be tested in the following cases.

Internal client
^^^^^^^^^^^^^^^

This application is a simple command to be run on the debug cli to test connectivity & throughput on QUIC over the debug cli (vppctl). It does not reflect reality and is mostly used for internal tests.

* Run ``test echo server uri quic://1.1.1.1/1234`` on your first instance
* Then ``test echo client uri quic://20.20.1.1/1`` on the second one

Source for the internal client lives in ``src/plugins/hs_apps/echo_client.c``

External client
^^^^^^^^^^^^^^^

This setup reflects the use case of an app developer using vpp to create a quic client / server. The application is an external binary that connects to VPP via its binary API.

After having setup two interconnected vpps, you can attach the quic_echo binary to each of them.

* The binary can be found in ``./build-root/build-vpp[_debug]-native/vpp/bin/quic_echo``
* To run the client & server use ``quic_echo socket-name /vpp.sock client|server uri quic://1.1.1.1/1234``
* Several options are available to customize the amount of data sent, number of threads, logging and timing.

The behavior of this app when run with ``nclient 2/4`` is two first establish 2 connections with the given peer, and once everything has been opened start opening 4 quic streams, and transmit data. Flow is as follows.

.. image:: /_images/quic_plugin_echo_flow.png

This allows timing of either the whole setup & teardown or specific phases in assessing the protocol's performance

Source for the internal client lives in ``src/plugins/hs_apps/sapi/quic_echo.c``

VCL client
^^^^^^^^^^

The hoststack exposes a simplified API call the VCL (blocking posix like calls), this API is used by a sample client & server implementation that supports QUIC, TCP and UDP.

* The binaries can be found in ``./build-root/build-vpp[_debug]-native/vpp/bin/``
* Create the VCL conf files ``echo "vcl { api-socket-name /vpp.sock }" | tee /tmp/vcl.conf]``
* For the server ``VCL_CONFIG=/tmp/vcl.conf ; vcl_test_server -p QUIC 1234"``
* For the client ``VCL_CONFIG=/tmp/vcl.conf ; vcl_test_client -p QUIC 1.1.1.1 1234"``

Source for the internal client lives in ``src/plugins/hs_apps/vcl/vcl_test_client.c``

A basic usage is the following client side

.. code-block:: C

  #include <vcl/vppcom.h>
  int fd = vppcom_session_create (VPPCOM_PROTO_QUIC);
  vppcom_session_tls_add_cert (/* args */);
  vppcom_session_tls_add_key (/* args */);
  vppcom_session_connect (fd, "quic://1.1.1.1/1234"); /* create a quic connection */
  int sfd = vppcom_session_create (VPPCOM_PROTO_QUIC);
  vppcom_session_stream_connect (sfd, fd); /* open a quic stream on the connection*/
  vppcom_session_write (sfd, buf, n);

Server side

.. code-block:: C

  #include <vcl/vppcom.h>
  int lfd = vppcom_session_create (VPPCOM_PROTO_QUIC);
  vppcom_session_tls_add_cert (/* args */);
  vppcom_session_tls_add_key (/* args */);
  vppcom_session_bind (fd, "quic://1.1.1.1/1234");
  vppcom_session_listen (fd);
  int fd = vppcom_session_accept (lfd); /* accept quic connection*/
  vppcom_session_is_connectable_listener (fd); /* is true */
  int sfd = vppcom_session_accept (fd); /* accept quic stream */
  vppcom_session_is_connectable_listener (sfd); /* is false */
  vppcom_session_read (sfd, buf, n);


Internal Mechanics
------------------

QUIC constructs are exposed as follows:

- QUIC connections and streams are both regular host stack session, exposed via the API with their 64bits handle.
- QUIC connections can be created and destroyed with regular ``connect`` and ``close`` calls with ``TRANSPORT_PROTO_QUIC``.
- Streams can be opened in a connection by calling ``connect`` again and passing the handle of the connection to which the new stream should belong.
- Streams can be closed with a regular ``close`` call.
- Streams opened by peers can be accepted from the sessions corresponding to QUIC connections.
- Data can ba exchanged by using the regular ``send`` and ``recv`` calls on the stream sessions.

Data structures
^^^^^^^^^^^^^^^

Quic relies on the hoststack constructs, namely applications, sessions, transport_connections, and app_listeners. When listening on a port with the quic protocol, an external application :

* Attaches to vpp and register an ``application``
* It creates an ``app_listener`` and a ``quic_listen_session``.
* The ``quic_listen_session`` relies on a ``transport_connection`` (``lctx``) to access the underlying ``udp_listen_session`` that will receive packets.
* Upon connection request, we create the same data structure (``quic_session``, ``qctx``, ``udp_session``) and pass a handle to the ``quic_session`` in the accept callback to acknowledge the creation of a quic connection. All further UDP datagrams for the peers at each end of the connection will be exchanged through the ``udp_session``
* Upon receiving a Stream opening request, we create the ``stream_session`` and its transport ``sctx`` and pass the handle to the ``stream_session`` back to the app. Here we don't have any UDP datastructures, as all datagrams are bound to the connection.


Those structures are linked as follows :

.. image:: /_images/quic_plugin_datastructures.png