<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE rfc [
<!ENTITY nbsp "&#160;">
<!ENTITY zwsp "&#8203;">
<!ENTITY nbhy "&#8209;">
<!ENTITY wj "&#8288;">
]>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" category="exp" ipr="trust200902" docName="draft-dreibholz-taps-neat-socketapi-19" obsoletes="" updates="" xml:lang="en" tocInclude="true" symRefs="false" version="3">
 <?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
 <front>
  <title abbrev="NEAT Sockets API">
NEAT Sockets API
</title>
  <seriesInfo name="Internet-Draft" value="draft-dreibholz-taps-neat-socketapi-19" />
  <!-- ************** THOMAS DREIBHOLZ *************** -->
  <author initials="T." surname="Dreibholz" fullname="Thomas Dreibholz">
   <organization abbrev="SimulaMet">Simula Metropolitan Centre for Digital Engineering</organization>
   <address>
    <postal>
     <street>Stensberggata 27</street>
     <city>0170 Oslo</city>
     <country>Norway</country>
    </postal>
    <email>dreibh@simula.no</email>
    <uri>https://www.simula.no/people/dreibh</uri>
   </address>
  </author>
  <date day="16" month="September" year="2026" />
  <keyword>Internet-Draft</keyword>
  <abstract>
   <t>
    This document describes a BSD Sockets-like API on top of the
    callback-based NEAT User API. This facilitates porting existing
    applications to use a subset of NEAT's functionality.
   </t>
  </abstract>
 </front>
 <middle>
  <section numbered="true" toc="default">
   <name>Introduction</name>
   <t>
    The NEAT project <xref target="ANRW2017" />, <xref target="NEAT-D1.1" />,
    <xref target="I-D.ietf-taps-transports-usage" />,
    <xref target="I-D.gjessing-taps-minset" />, <xref target="NEAT-Website" />
    wants to achieve a complete redesign of the way in which Internet
    applications interact with the network. Our goal is to allow network
    "services" offered to applications - such as reliability, low-delay
    communication or security - to be dynamically tailored based on
    application demands, current network conditions, hardware capabilities or
    local policies, and also to support the integration of new network
    functionality in an evolutionary fashion.
   </t>
   <t>
    This document describes the NEAT Sockets API on top of the callback-based
    NEAT User API <xref target="I-D.fairhurst-taps-neat" />. It provides a BSD
    Sockets-like API that facilitates porting existing applications to use a
    subset of NEAT's functionality. For further information on NEAT, see also
    <xref target="ANRW2017" />, <xref target="NEAT-D1.1" />,
    <xref target="NEAT-D1.3" />, <xref target="NEAT-D2.2" />,
    <xref target="NEAT-D2.3" />.
   </t>
   <section numbered="true" toc="default">
    <name>Conventions</name>
    <t>
     The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>",
     "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
     NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>",
     "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
     "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are
     to be interpreted as described in BCP 14 <xref target="RFC2119" />
     <xref target="RFC8174" /> when, and only when, they appear in all
     capitals, as shown here.
    </t>
   </section>
  </section>
  <section numbered="true" toc="default">
   <name>Initialisation and Clean-Up</name>
   <section numbered="true" toc="default">
    <name>nsa_init()</name>
    <t>
     nsa_init() is used to explicitly initialise the NEAT Sockets API. In the
     usual case, however, the NEAT Sockets API is automatically initialized
     when creating a NEAT socket. Explicit initialisation may only be
     necessary in a multi-threaded program, in order to avoid parallel
     initialisation calls.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_init()
]]></artwork>
    <t>Return Value:</t>
    <t>
     nsa_init() returns the new NEAT socket descriptor, or -1 in case of
     error. The error code will be set in the errno variable.
    </t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_cleanup()</name>
    <t>
     nsa_cleanup() is used to free all resources allocated by NEAT. Note, that
     the NEAT Sockets API is automatically initialized when creating a NEAT
     socket.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
void nsa_cleanup()
]]></artwork>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_map_socket()</name>
    <t>
     nsa_map_socket() is used to map a system socket descriptor into the NEAT
     socket descriptor space. This is useful for using NEAT API functions as
     wrapper to calls on non-NEAT sockets. Mapped socket descriptors can be
     unmapped by using nsa_unmap_socket().
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_map_socket(int systemSD, int neatSD)
]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>systemSD:</dt>
     <dd>System socket descriptor.</dd>
     <dt>neatSD:</dt>
     <dd>Desired NEAT socket descriptor; -1 for automatic allocation.</dd>
    </dl>
    <t>Return Value:</t>
    <t>
     nsa_map_socket() returns the new NEAT socket descriptor, or -1 in case of
     error. The error code will be set in the errno variable.
    </t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_unmap_socket()</name>
    <t>
     nsa_unmap_socket() is used to unmap a system socket descriptor from the
     NEAT socket descriptor space.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_unmap_socket(int neatSD)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>neatSD:</dt>
     <dd>NEAT socket descriptor.</dd>
    </dl>
   </section>
  </section>
  <section numbered="true" toc="default">
   <name>Connection Establishment and Teardown</name>
   <section numbered="true" toc="default">
    <name>nsa_socket()</name>
    <t>
     nsa_socket() creates a new NEAT socket. The NEAT socket can either be a
     wrapper around the NEAT User API (if properties are specified) or be a
     wrapper around a system socket (if no properties are specified).
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_socket(int domain, int type, int protocol,
               const char* properties)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>domain:</dt>
     <dd>Domain for system socket (e.g. AF_INET).</dd>
     <dt>type:</dt>
     <dd>Type for system socket (SOCK_SEQPACKET).</dd>
     <dt>protocol:</dt>
     <dd>Protocol for system socket (IPPROTO_SCTP).</dd>
     <dt>properties:</dt>
     <dd>Properties for NEAT Core socket.</dd>
    </dl>
    <t>Return Value:</t>
    <t>
     nsa_socket() returns the NEAT socket descriptor in case of success, or -1
     in case of error. The error code will be set in the errno variable.
    </t>
    <t>See the socket() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_socketpair()</name>
    <t>
     nsa_socketpair() is a wrapper around the socketpair() call, returning
     NEAT socket descriptors instead. Note, that socketpair() only supports
     AF_UNIX sockets, i.e. this function is just a wrapper for the system
     function.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_socketpair(int domain, int type, int protocol,
                   const char* properties)]]></artwork>
    <t>See the socketpair() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_close()</name>
    <t>nsa_close() closes a given NEAT socket.</t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_close(int sockfd)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
    </dl>
    <t>
     nsa_close() returns 0 in case of success, or -1 in case of error. The
     error code will be set in the errno variable.
    </t>
    <t>See the close() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_fcntl()</name>
    <t>nsa_fcntl() manipulates a given NEAT socket.</t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_fcntl(int sockfd, int cmd, ...)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>cmd:</dt>
     <dd>Command.</dd>
     <dt>...:</dt>
     <dd>Command-specific arguments.</dd>
    </dl>
    <t>nsa_fcntl() returns a command-specific value.</t>
    <t>For NEAT sockets, the following commands are specified:</t>
    <dl newline="false" spacing="normal">
     <dt>F_GETFL:</dt>
     <dd>
      Obtain value of the socket descriptor status flags. For NEAT sockets,
      the flag O_NONBLOCK specifies whether the socket is non-blocking. By
      default, it is blocking (i.e. O_NONBLOCK is not set).
     </dd>
     <dt>F_SETFL:</dt>
     <dd>
      Set value of the socket descriptor status flags. For NEAT sockets, the
      flag O_NONBLOCK specifies whether the socket is non-blocking. By
      default, it is blocking (i.e. O_NONBLOCK is not set). F_SETFL can then
      be used to change the blocking mode.
     </dd>
    </dl>
    <t>See the fcntl() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_bind()</name>
    <t>
     nsa_bind() binds a given NEAT socket to a given address. Note: this
     function is provided as legacy wrapper, and it is
     <bcp14>RECOMMENDED</bcp14> to use nsa_bindn() instead. Note further, that
     nsa_bind() also supports a single address only (i.e. no multi-homing).
     nsa_bindx() <bcp14>SHOULD</bcp14> be used instead to support
     multi-homing.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_bind(int sockfd,
             const struct sockaddr* addr, socklen_t addrlen,
             struct neat_tlv* opt, const int optcnt)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>addr:</dt>
     <dd>Address to bind to.</dd>
     <dt>addrlen:</dt>
     <dd>Length of the address structure "addr".</dd>
     <dt>opt:</dt>
     <dd>NEAT options (NULL, if there are none).</dd>
     <dt>optcnt:</dt>
     <dd>Number of NEAT options provided by "opt".</dd>
    </dl>
    <t>
     nsa_bind() returns 0 in case of success, or -1 in case of error. The
     error code will be set in the errno variable.
    </t>
    <t>See the bind() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_bindx()</name>
    <t>
     nsa_bindx() binds a given NEAT socket to a given set of addresses. Note:
     this function is provided as legacy wrapper, and it is
     <bcp14>RECOMMENDED</bcp14> to use nsa_bindn() instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_bindx(int sockfd, const struct sockaddr* addrs, int addrcnt,
              int flags,
              struct neat_tlv* opt, const int optcnt)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>addrs:</dt>
     <dd>Addresses to bind to.</dd>
     <dt>addrcnt:</dt>
     <dd>Number of addresses in "addr".</dd>
     <dt>flags:</dt>
     <dd>Optional flags (0, if there are none).</dd>
     <dt>opt:</dt>
     <dd>NEAT options (NULL, if there are none).</dd>
     <dt>optcnt:</dt>
     <dd>Number of NEAT options provided by "opt".</dd>
    </dl>
    <t>
     nsa_bindx() returns 0 in case of success, or -1 in case of error. The
     error code will be set in the errno variable.
    </t>
    <t>See the sctp_bindx() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_bindn()</name>
    <t>
     nsa_bindn() binds a given NEAT socket to a given port. NEAT takes care of
     handling local addresses.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_bindn(int sockfd, uint16_t port, int flags,
              struct neat_tlv* opt, const int optcnt)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>port:</dt>
     <dd>Port number to bind to.</dd>
     <dt>flags:</dt>
     <dd>Optional flags (0, if there are none).</dd>
     <dt>opt:</dt>
     <dd>NEAT options (NULL, if there are none).</dd>
     <dt>optcnt:</dt>
     <dd>Number of NEAT options provided by "opt".</dd>
    </dl>
    <t>
     nsa_bindn() returns 0 in case of success, or -1 in case of error. The
     error code will be set in the errno variable.
    </t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_connect()</name>
    <t>
     nsa_connect() connects a given NEAT socket to a given remote address.
     Note: this function is provided as legacy wrapper, and it is
     <bcp14>RECOMMENDED</bcp14> to use nsa_connectn() instead. Note further,
     that nsa_connect() also supports a single address only (i.e. no
     multi-homing). nsa_connectx() <bcp14>SHOULD</bcp14> be used instead to
     support multi-homing.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_connect(int sockfd,
                const struct sockaddr* addr, socklen_t addrlen,
                struct neat_tlv* opt, const int optcnt)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>addr:</dt>
     <dd>Address to connect to.</dd>
     <dt>addrlen:</dt>
     <dd>Length of the address structure "addr".</dd>
     <dt>opt:</dt>
     <dd>NEAT options (NULL, if there are none).</dd>
     <dt>optcnt:</dt>
     <dd>Number of NEAT options provided by "opt".</dd>
    </dl>
    <t>
     nsa_connect() returns 0 in case of success, or -1 in case of error. The
     error code will be set in the errno variable.
    </t>
    <t>See the connect() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_connectx()</name>
    <t>
     nsa_connectx() connects a given NEAT socket to a given set of remote
     addresses. Note: this function is provided as legacy wrapper, and it is
     <bcp14>RECOMMENDED</bcp14> to use nsa_connectn() instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_connectx(int sockfd,
                 const struct sockaddr* addrs, int addrcnt,
                 neat_assoc_t* id,
                 struct neat_tlv* opt, const int optcnt)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>addrs:</dt>
     <dd>Addresses to connect to.</dd>
     <dt>addrcnt:</dt>
     <dd>Number of addresses in "addr".</dd>
     <dt>id</dt>
     <dd>Pointer to store association ID to (not used yet, use NULL!).</dd>
     <dt>opt:</dt>
     <dd>NEAT options (NULL, if there are none).</dd>
     <dt>optcnt:</dt>
     <dd>Number of NEAT options provided by "opt".</dd>
    </dl>
    <t>
     nsa_connectx() returns 0 in case of success, or -1 in case of error. The
     error code will be set in the errno variable.
    </t>
    <t>See the sctp_connectx() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_connectn()</name>
    <t>
     nsa_connectn() connects a given NEAT socket to a given remote name and
     port. The remote name is resolved by NEAT to corresponding remote
     addresses.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_connectn(int sockfd, const char* name, const uint16_t port,
                 neat_assoc_t* id,
                 struct neat_tlv* opt, const int optcnt)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>name:</dt>
     <dd>Remote name to connect to.</dd>
     <dt>port:</dt>
     <dd>Remote port number to connect to.</dd>
     <dt>id</dt>
     <dd>Pointer to store association ID to (not used yet, use NULL!).</dd>
     <dt>opt:</dt>
     <dd>NEAT options (NULL, if there are none).</dd>
     <dt>optcnt:</dt>
     <dd>Number of NEAT options provided by "opt".</dd>
    </dl>
    <t>
     nsa_connectn() returns 0 in case of success, or -1 in case of error. The
     error code will be set in the errno variable.
    </t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_listen()</name>
    <t>
     nsa_listen() marks a given NEAT socket as listening socket, i.e.
     accepting incoming connections.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_listen(int sockfd, int backlog)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>backlog:</dt>
     <dd>
      Defines the maximum length to which the queue of pending connections for
      "sockfd" may grow.
     </dd>
    </dl>
    <t>
     nsa_listen() returns 0 in case of success, or -1 in case of error. The
     error code will be set in the errno variable.
    </t>
    <t>See the listen() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_accept()</name>
    <t>
     nsa_accept() extracts the first connection request in the queue of
     pending connections for a listening NEAT socket, creates a new connected
     socket, and returns a new NEAT socket descriptor referring to that
     socket.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>addr:</dt>
     <dd>
      Pointer to storage space to store the peer's primary address to (or
      NULL, if address is not needed).
     </dd>
     <dt>addrlen:</dt>
     <dd>
      Pointer to variable with size of the storage in "addr" (or NULL, if
      address is not needed).
     </dd>
    </dl>
    <t>
     nsa_accept() returns the new NEAT socket descriptor in case of success,
     or -1 in case of error. The error code will be set in the errno variable.
     In case of success, the peer's primary address is stored in "addr", if
     there is sufficient space. The variable pointer to by "addrlen" will then
     contain the actual address size.
    </t>
    <t>See the accept() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_accept4()</name>
    <t>
     nsa_accept4() extracts the first connection request in the queue of
     pending connections for a listening NEAT socket, creates a new connected
     socket, and returns a new NEAT socket descriptor referring to that
     socket. If successful, and flags!=0, nsa_accept4() furthermore makes the
     new socket non-blocking (SOCK_NONBLOCK flag) and/or close-on-exec
     (SOCK_CLOEXEC flag). For flags==0, the behaviour is identical to
     nsa_accept().
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_accept4(int sockfd,
                struct sockaddr* addr, socklen_t* addrlen,
                int flags)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>addr:</dt>
     <dd>
      Pointer to storage space to store the peer's primary address to (or
      NULL, if address is not needed).
     </dd>
     <dt>addrlen:</dt>
     <dd>
      Pointer to variable with size of the storage in "addr" (or NULL, if
      address is not needed).
     </dd>
    </dl>
    <t>
     nsa_accept4() returns the new NEAT socket descriptor in case of success,
     or -1 in case of error. The error code will be set in the errno variable.
     In case of success, the peer's primary address is stored in "addr", if
     there is sufficient space. The variable pointer to by "addrlen" will then
     contain the actual address size.
    </t>
    <t>See the accept() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_shutdown()</name>
    <t>nsa_shutdown() shuts down the connection of a given NEAT socket.</t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_shutdown(int sockfd, int how)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>how:</dt>
     <dd>Not used for NEAT sockets (set to SHUT_RDWR).</dd>
    </dl>
    <t>
     nsa_shutdown() returns 0 in case of success, or -1 in case of error. The
     error code will be set in the errno variable.
    </t>
    <t>See the shutdown() documentation for details.</t>
   </section>
   <!--
   <section title="nsa_peeloff()">
    <t>...</t>
    <t>Function Prototype:</t>
    <figure><artwork><![CDATA[
int nsa_peeloff(int sockfd, neat_assoc_t id)]]></artwork>
</figure>
</section>
-->
  </section>
  <section numbered="true" toc="default">
   <name>Options Handling</name>
   <section numbered="true" toc="default">
    <name>nsa_getsockopt()</name>
    <t>nsa_getsockopt() gets a socket option of a given NEAT socket.</t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_getsockopt(int sockfd, int level, int optname,
                   void* optval, socklen_t* optlen)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>level:</dt>
     <dd>Option level.</dd>
     <dt>optname:</dt>
     <dd>Option number.</dd>
     <dt>optval:</dt>
     <dd>Buffer to store option value to.</dd>
     <dt>optlen:</dt>
     <dd>Pointer to variable with length of the buffer in "optval".</dd>
    </dl>
    <t>
     nsa_getsockopt() returns 0 in case of success, or -1 in case of error.
     The error code will be set in the errno variable.
    </t>
    <t>See the getsockopt() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_setsockopt()</name>
    <t>nsa_getsockopt() sets a socket option of a given NEAT socket.</t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_setsockopt(int sockfd, int level, int optname,
                   const void* optval, socklen_t optlen)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>level:</dt>
     <dd>Option level.</dd>
     <dt>optname:</dt>
     <dd>Option number.</dd>
     <dt>optval:</dt>
     <dd>Buffer with option value to set.</dd>
     <dt>optlen:</dt>
     <dd>Length of buffer with option value.</dd>
    </dl>
    <t>
     nsa_setsockopt() returns 0 in case of success, or -1 in case of error.
     The error code will be set in the errno variable.
    </t>
    <t>See the setsockopt() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_opt_info()</name>
    <t>nsa_opt_info() gets a socket option of a given NEAT socket.</t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_opt_info(int sockfd, neat_assoc_t id,
                 int opt, void* arg, socklen_t* size)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>id:</dt>
     <dd>Association identifier (0 in case of 1:1-style sockets).</dd>
     <dt>opt:</dt>
     <dd>Option number.</dd>
     <dt>arg:</dt>
     <dd>Buffer to store option value to.</dd>
     <dt>size:</dt>
     <dd>Pointer to variable with length of the buffer in "arg".</dd>
    </dl>
    <t>
     nsa_opt_info() returns 0 in case of success, or -1 in case of error. The
     error code will be set in the errno variable.
    </t>
    <t>See the sctp_opt_info() documentation for details.</t>
   </section>
  </section>
  <section numbered="true" toc="default">
   <name>Security</name>
   <section numbered="true" toc="default">
    <name>nsa_set_secure_identity()</name>
    <t>TBD.</t>
   </section>
   <section numbered="true" toc="default">
    <name>...</name>
    <t>TBD.</t>
   </section>
  </section>
  <section numbered="true" toc="default">
   <name>Input/Output Handling</name>
   <section numbered="true" toc="default">
    <name>nsa_write()</name>
    <t>
     nsa_write() sends data over a given connected NEAT socket. For NEAT
     sockets, nsa_write() is equal to nsa_send() with "flags" set to 0.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
ssize_t nsa_write(int fd, const void* buf, size_t len)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>fd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>buf:</dt>
     <dd>Data to send.</dd>
     <dt>len:</dt>
     <dd>Length of data to send.</dd>
    </dl>
    <t>
     nsa_write() returns the number of sent bytes in case of success, or -1 in
     case of error. The error code will be set in the errno variable.
    </t>
    <t>See the write() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_writev()</name>
    <t>
     nsa_writev() sends data over a given connected NEAT socket. The data is
     provided by an iovec structure.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
ssize_t nsa_writev(int fd, const struct iovec* iov, int iovcnt)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>iov:</dt>
     <dd>Data to send provided as iovec structures.</dd>
     <dt>iovcnt:</dt>
     <dd>Number of provided iovec structures.</dd>
    </dl>
    <t>
     nsa_writev() returns the number of sent bytes in case of success, or -1
     in case of error. The error code will be set in the errno variable.
    </t>
    <t>See the writev() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_pwrite()</name>
    <t>
     nsa_pwrite() is a wrapper around the pwrite() call, using a NEAT socket
     descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
ssize_t nsa_pwrite(int fd, const void* buf, size_t len, off_t offset)]]></artwork>
    <t>See the pwrite() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_pwrite64()</name>
    <t>
     nsa_pwrite64() is a wrapper around the pwrite64() call, using a NEAT
     socket descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
ssize_t nsa_pwrite(int fd, const void* buf, size_t len,
                   off64_t offset)]]></artwork>
    <t>See the pwrite64() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_pwritev()</name>
    <t>
     nsa_pwritev() is a wrapper around the pwritev() call, using a NEAT socket
     descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
ssize_t nsa_pwritev(int fd, const struct iovec* iov, int iovcnt,
                    off_t offset)]]></artwork>
    <t>See the pwritev() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_pwritev64()</name>
    <t>
     nsa_pwritev64() is a wrapper around the pwritev64() call, using a NEAT
     socket descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
ssize_t nsa_pwritev(int fd, const struct iovec* iov, int iovcnt,
                    off64_t offset)]]></artwork>
    <t>See the pwritev64() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_send()</name>
    <t>nsa_send() sends data over a given connected NEAT socket.</t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
ssize_t nsa_send(int sockfd, const void* buf, size_t len, int flags)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>buf:</dt>
     <dd>Data to send.</dd>
     <dt>len:</dt>
     <dd>Length of data to send.</dd>
     <dt>flags:</dt>
     <dd>Optional flags (0, if there are none).</dd>
    </dl>
    <t>
     nsa_send() returns the number of sent bytes in case of success, or -1 in
     case of error. The error code will be set in the errno variable.
    </t>
    <t>See the send() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_sendto()</name>
    <t>
     nsa_sendto() is a wrapper around the sendto() call, using NEAT socket
     descriptors instead. Note: this function is provided as legacy wrapper,
     and it is <bcp14>RECOMMENDED</bcp14> to use nsa_send() instead. On NEAT
     sockets, a provided destination address is ignored.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
ssize_t nsa_sendto(int sockfd, const void* buf, size_t len,
                   int flags,
                   const struct sockaddr* to, socklen_t tolen)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>buf:</dt>
     <dd>Data to send.</dd>
     <dt>len:</dt>
     <dd>Length of data to send.</dd>
     <dt>flags:</dt>
     <dd>Optional flags (0, if there are none).</dd>
     <dt>to:</dt>
     <dd>Address to send data to (ignored for NEAT sockets).</dd>
     <dt>tolen:</dt>
     <dd>Length of address to send data to (ignored for NEAT sockets).</dd>
    </dl>
    <t>
     nsa_sendto() returns the number of sent bytes in case of success, or -1
     in case of error. The error code will be set in the errno variable.
    </t>
    <t>See the send() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_sendmsg()</name>
    <t>
     nsa_sendmsg() sends data over a given connected NEAT socket. The data and
     control information is provided by a msghdr structure. On NEAT sockets, a
     provided destination address is ignored.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
ssize_t nsa_sendmsg(int sockfd, const struct msghdr* msg, int flags)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>msg:</dt>
     <dd>
      Data to send and corresponding control information as msghdr structure.
     </dd>
     <dt>flags:</dt>
     <dd>Optional flags (0, if there are none).</dd>
    </dl>
    <t>
     nsa_sendmsg() returns the number of sent bytes in case of success, or -1
     in case of error. The error code will be set in the errno variable.
    </t>
    <t>See the sendmsg() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_sendv()</name>
    <t>
     nsa_sendv() sends data over a given connected NEAT socket. The data and
     control information is provided by iovec and info structures. On NEAT
     sockets, a provided destination address is ignored.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
ssize_t nsa_sendv(int sockfd, struct iovec* iov, int iovcnt,
                  struct sockaddr* to, int tocnt,
                  void* info, socklen_t infolen,
                  unsigned int infotype, int flags)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>iov:</dt>
     <dd>Data to send provided as iovec structures.</dd>
     <dt>iovcnt:</dt>
     <dd>Number of provided iovec structures.</dd>
     <dt>to:</dt>
     <dd>Address(es) to send data to (ignored for NEAT sockets).</dd>
     <dt>tocnt:</dt>
     <dd>
      Number of of addresses to send data to (ignored for NEAT sockets).
     </dd>
     <dt>info:</dt>
     <dd>Control information.</dd>
     <dt>infolen:</dt>
     <dd>Length of control information.</dd>
     <dt>infotype:</dt>
     <dd>Type of control information.</dd>
     <dt>flags:</dt>
     <dd>Optional flags (0, if there are none).</dd>
    </dl>
    <t>
     nsa_sendv() returns the number of sent bytes in case of success, or -1 in
     case of error. The error code will be set in the errno variable.
    </t>
    <t>See the sctp_sendv() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_read()</name>
    <t>
     nsa_read() reads data from a given connected NEAT socket. For NEAT
     sockets, nsa_read() is equal to nsa_recv() with "flags" set to 0.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
ssize_t nsa_read(int fd, void* buf, size_t len)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>fd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>buf:</dt>
     <dd>Buffer to store read data to.</dd>
     <dt>len:</dt>
     <dd>Length of the storage buffer.</dd>
    </dl>
    <t>
     nsa_read() returns the number of read bytes in case of success, 0 in case
     of connection shutdown, or -1 in case of error. The error code will be
     set in the errno variable.
    </t>
    <t>See the read() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_readv()</name>
    <t>
     nsa_readv() reads data from a given connected NEAT socket. The data
     information buffers are provided by an iovec structure.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
ssize_t nsa_readv(int fd, const struct iovec* iov, int iovcnt)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>fd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>iov:</dt>
     <dd>Data to send provided as iovec structures.</dd>
     <dt>iovcnt:</dt>
     <dd>Number of provided iovec structures.</dd>
    </dl>
    <t>
     nsa_readv() returns the number of read bytes in case of success, 0 in
     case of connection shutdown, or -1 in case of error. The error code will
     be set in the errno variable.
    </t>
    <t>See the readv() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_pread()</name>
    <t>
     nsa_pread() is a wrapper around the pread() call, using a NEAT socket
     descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
ssize_t nsa_pread(int fd, void* buf, size_t len, off_t offset)]]></artwork>
    <t>See the pread() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_pread64()</name>
    <t>
     nsa_pread64() is a wrapper around the pread64() call, using a NEAT socket
     descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
ssize_t nsa_pread(int fd, void* buf, size_t len, off_t offset)]]></artwork>
    <t>See the pread64() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_preadv()</name>
    <t>
     nsa_preadv() is a wrapper around the preadv() call, using a NEAT socket
     descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
ssize_t nsa_preadv(int fd, const struct iovec* iov, int iovcnt,
                   off64_t offset)]]></artwork>
    <t>See the preadv() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_preadv64()</name>
    <t>
     nsa_preadv64() is a wrapper around the preadv64() call, using a NEAT
     socket descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
ssize_t nsa_preadv(int fd, const struct iovec* iov, int iovcnt,
                   off64_t offset)]]></artwork>
    <t>See the preadv64() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_recv()</name>
    <t>nsa_recv() reads data from a given connected NEAT socket.</t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
ssize_t nsa_recv(int sockfd, void* buf, size_t len, int flags)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>buf:</dt>
     <dd>Buffer to store read data to.</dd>
     <dt>len:</dt>
     <dd>Length of the storage buffer.</dd>
     <dt>flags:</dt>
     <dd>Optional flags (0, if there are none).</dd>
    </dl>
    <t>
     nsa_recv() returns the number of read bytes in case of success, 0 in case
     of connection shutdown, or -1 in case of error. The error code will be
     set in the errno variable.
    </t>
    <t>See the recv() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_recvfrom()</name>
    <t>
     nsa_recvfrom() reads data from a given connected NEAT socket. The peer's
     sending address of the data (if possible and useful for underlying
     transport protocol) is obtained as well. Note: this function is provided
     as legacy wrapper, and it is <bcp14>RECOMMENDED</bcp14> to use nsa_recv()
     instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
ssize_t nsa_recvfrom(int sockfd, void* buf, size_t len, int flags,
                     struct sockaddr* from, socklen_t* fromlen)]]></artwork>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>buf:</dt>
     <dd>Buffer to store read data to.</dd>
     <dt>len:</dt>
     <dd>Length of the storage buffer.</dd>
     <dt>flags:</dt>
     <dd>Optional flags (0, if there are none).</dd>
     <dt>from:</dt>
     <dd>
      Pointer to storage space to store the peer's primary address to (or
      NULL, if address is not needed).
     </dd>
     <dt>fromlen:</dt>
     <dd>
      Pointer to variable with size of the storage in "from" (or NULL, if
      address is not needed).
     </dd>
    </dl>
    <t>
     nsa_recvfrom() returns the number of read bytes in case of success, 0 in
     case of connection shutdown, or -1 in case of error. The error code will
     be set in the errno variable. In case of success, the peer's sending
     address (if possible and useful for underlying transport protocol) may be
     stored in "from", if there is sufficient space. The variable pointer to
     by "fromlen" will then contain the actual address size.
    </t>
    <t>See the recvfrom() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_recvmsg()</name>
    <t>
     nsa_recvmsg() reads data from a given connected NEAT socket. The data and
     control information buffers are provided by a msghdr structure.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
ssize_t nsa_recvmsg(int sockfd, struct msghdr* msg, int flags)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>msg:</dt>
     <dd>
      Data to send and corresponding control information as msghdr structure.
     </dd>
     <dt>flags:</dt>
     <dd>Optional flags (0, if there are none).</dd>
    </dl>
    <t>
     nsa_recvmsg() returns the number of read bytes in case of success, 0 in
     case of connection shutdown, or -1 in case of error. The error code will
     be set in the errno variable.
    </t>
    <t>See the recvmsg() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_recvv()</name>
    <t>
     nsa_recvv() reads data from a given connected NEAT socket. The data and
     control information buffers are provided by iovec and info structures.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
ssize_t nsa_recvv(int sockfd, struct iovec* iov, int iovcnt,
                  struct sockaddr* from, socklen_t* fromlen,
                  void* info, socklen_t* infolen,
                  unsigned int* infotype, int* msg_flags)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>iov:</dt>
     <dd>Data to send provided as iovec structures.</dd>
     <dt>iovcnt:</dt>
     <dd>Number of provided iovec structures.</dd>
     <dt>from:</dt>
     <dd>
      Pointer to storage space to store the peer's primary address to (or
      NULL, if address is not needed).
     </dd>
     <dt>fromlen:</dt>
     <dd>
      Pointer to variable with size of the storage in "from" (or NULL, if
      address is not needed).
     </dd>
     <dt>info:</dt>
     <dd>Pointer to storage space for control information.</dd>
     <dt>infolen:</dt>
     <dd>Pointer to variable with length of control information.</dd>
     <dt>infotype:</dt>
     <dd>Pointer to variable for storing the control information type to.</dd>
     <dt>flags:</dt>
     <dd>Pointer to variable with optional flags.</dd>
    </dl>
    <t>
     nsa_recvv() returns the number of sent received in case of success, or -1
     in case of error. The error code will be set in the errno variable.
    </t>
    <t>See the sctp_recvv() documentation for details.</t>
   </section>
  </section>
  <section numbered="true" toc="default">
   <name>Poll and Select</name>
   <section numbered="true" toc="default">
    <name>nsa_poll()</name>
    <t>
     nsa_poll() waits for activity (input/output/error/...) on a set of given
     NEAT sockets.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_poll(struct pollfd* ufds, const nfds_t nfds, int timeout)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>ufds:</dt>
     <dd>
      NEAT socket descriptor and requested activity for each NEAT socket.
     </dd>
     <dt>nfds:</dt>
     <dd>Number of sockets given by "ufds".</dd>
     <dt>timeout:</dt>
     <dd>Timeout in milliseconds.</dd>
    </dl>
    <t>
     nsa_poll() returns the number of NEAT sockets with activity in case of
     success, 0 in case of timeout, or -1 in case of error. The error code
     will be set in the errno variable.
    </t>
    <t>See the poll() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_select()</name>
    <t>
     nsa_select() is a wrapper around the select() call, using NEAT socket
     descriptors instead. Note: this function is provided as legacy wrapper,
     and it is <bcp14>RECOMMENDED</bcp14> to use nsa_poll() instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_select(int n,
               fd_set* readfds, fd_set* writefds, fd_set* exceptfds,
               struct timeval* timeout)]]></artwork>
    <t>See the select() documentation for details.</t>
   </section>
  </section>
  <section numbered="true" toc="default">
   <name>Address Handling</name>
   <section numbered="true" toc="default">
    <name>nsa_getsockname()</name>
    <t>
     nsa_getsockname() obtains the first local address of a socket. Note: this
     function is provided as legacy wrapper, and it is
     <bcp14>RECOMMENDED</bcp14> to use nsa_getladdrs() instead to support
     multi-homed transport protocols!
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_getsockname(int sockfd,
                    struct sockaddr* name, socklen_t* namelen)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>name:</dt>
     <dd>Storage space for the address.</dd>
     <dt>namelen:</dt>
     <dd>Pointer to variable with the storage space's size.</dd>
    </dl>
    <t>Return Value:</t>
    <t>
     nsa_getsockname() returns 0 in case of success (with the actual address
     size stored into the "namelen" variable), or -1 in case of error. The
     error code will be set in the errno variable.
    </t>
    <t>See the getsockname() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_getpeername()</name>
    <t>
     nsa_getpeername() obtains the first remote address of a connected socket.
     Note: this function is provided as legacy wrapper, and it is
     <bcp14>RECOMMENDED</bcp14> to use nsa_getpaddrs() instead to support
     multi-homed transport protocols!
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_getpeername(int sockfd,
                    struct sockaddr* name, socklen_t* namelen)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>name:</dt>
     <dd>Storage space for the address.</dd>
     <dt>namelen:</dt>
     <dd>Pointer to variable with the storage space's size.</dd>
    </dl>
    <t>Return Value:</t>
    <t>
     nsa_getpeername() returns 0 in case of success (with the actual address
     size stored into the "namelen" variable), or -1 in case of error. The
     error code will be set in the errno variable.
    </t>
    <t>See the getpeername() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_getladdrs()</name>
    <t>
     nsa_getladdrs() obtains the local addresses of a socket. The storage
     space for the addresses will be automatically allocated and needs to be
     freed by nsa_freeladdrs().
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_getladdrs(int sockfd, neat_assoc_t id,
                  struct sockaddr** addrs)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>id:</dt>
     <dd>Association identifier (0 in case of 1:1-style sockets).</dd>
     <dt>addrs:</dt>
     <dd>Pointer to variable to store pointer to addresses to.</dd>
    </dl>
    <t>
     nsa_getladdrs() returns the number of addresses stored into a newly
     allocated space. The pointer to this space is stored into the variable
     provided by "addrs". In case of error, -1 is returned, and the error code
     will be set in the errno variable.
    </t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_freeladdrs()</name>
    <t>nsa_freeladdrs() frees addresses obtained by nsa_getladdrs().</t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
void nsa_freeladdrs(struct sockaddr* addrs)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>addrs:</dt>
     <dd>Pointer to addresses to be freed.</dd>
    </dl>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_getpaddrs()</name>
    <t>
     nsa_getpaddrs() obtains the remote addresses of a connected socket. The
     storage space for the addresses will be automatically allocated and needs
     to be freed by nsa_freepaddrs().
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_getpaddrs(int sockfd, neat_assoc_t id,
                  struct sockaddr** addrs)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>sockfd:</dt>
     <dd>NEAT socket descriptor.</dd>
     <dt>id:</dt>
     <dd>Association identifier (0 in case of 1:1-style sockets).</dd>
     <dt>addrs:</dt>
     <dd>Pointer to variable to store pointer to addresses to.</dd>
    </dl>
    <t>
     nsa_getpaddrs() returns the number of addresses stored into a newly
     allocated space. The pointer to this space is stored into the variable
     provided by "addrs". In case of error, -1 is returned, and the error code
     will be set in the errno variable.
    </t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_freepaddrs()</name>
    <t>nsa_freepaddrs() frees addresses obtained by nsa_getpaddrs().</t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
void nsa_freepaddrs(struct sockaddr* addrs)]]></artwork>
    <t>Arguments:</t>
    <dl newline="false" spacing="normal">
     <dt>addrs:</dt>
     <dd>Pointer to addresses to be freed.</dd>
    </dl>
   </section>
  </section>
  <section numbered="true" toc="default">
   <name>Miscellaneous</name>
   <t>
    This section contains miscellaneous wrapper functions, mostly around file
    I/O. Since Unix file descriptors are used together with socket descriptors
    in functions like poll(), select(), etc., it is necessary to wrap
    functions handling file descriptors as well.
   </t>
   <section numbered="true" toc="default">
    <name>nsa_open()</name>
    <t>
     nsa_open() is a wrapper around the open() call, returning a NEAT socket
     descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_open(const char* pathname, int flags, mode_t mode)]]></artwork>
    <t>See the open() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_creat()</name>
    <t>
     nsa_creat() is a wrapper around the creat() call, returning a NEAT socket
     descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_creat(const char* pathname, mode_t mode)]]></artwork>
    <t>See the creat() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_lockf()</name>
    <t>
     nsa_lockf() is a wrapper around the lockf() call, using a NEAT socket
     descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_lockf(int fd, int cmd, off_t len)]]></artwork>
    <t>See the lockf() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_lockf64()</name>
    <t>
     nsa_lockf64() is a wrapper around the lockf64() call, using a NEAT socket
     descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_lockf(int fd, int cmd, off64_t len)]]></artwork>
    <t>See the lockf64() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_flock()</name>
    <t>
     nsa_flock() is a wrapper around the flock() call, using a NEAT socket
     descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_flock(int fd, int operation)]]></artwork>
    <t>See the flock() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_fstat()</name>
    <t>
     nsa_fstat() is a wrapper around the fstat() call, using a NEAT socket
     descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_fstat(int fd, struct stat* buf)]]></artwork>
    <t>See the fstat() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_fpathconf()</name>
    <t>
     nsa_fpathconf() is a wrapper around the fpathconf() call, using a NEAT
     socket descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
long nsa_fpathconf(int fd, int name)]]></artwork>
    <t>See the fpathconf() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_fchown()</name>
    <t>
     nsa_fchown() is a wrapper around the fchown() call, using a NEAT socket
     descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_fchown(int fd, uid_t owner, gid_t group)]]></artwork>
    <t>See the fchown() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_fsync()</name>
    <t>
     nsa_fsync() is a wrapper around the fsync() call, using a NEAT socket
     descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_fsync(int fd)]]></artwork>
    <t>See the fsync() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_fdatasync()</name>
    <t>
     nsa_fdatasync() is a wrapper around the fdatasync() call, using a NEAT
     socket descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_fdatasync(int fd)]]></artwork>
    <t>See the fdatasync() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_syncfs()</name>
    <t>
     nsa_syncfs() is a wrapper around the syncfs() call, using a NEAT socket
     descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_syncfs(int fd)]]></artwork>
    <t>See the syncfs() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_dup2()</name>
    <t>
     nsa_dup2() is a wrapper around the dup2() call, using a NEAT socket
     descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_dup2(int oldfd, int newfd)]]></artwork>
    <t>See the dup2() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_dup3()</name>
    <t>
     nsa_dup3() is a wrapper around the dup3() call, using a NEAT socket
     descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_dup3(int oldfd, int newfd, int flags)]]></artwork>
    <t>See the dup3() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_dup()</name>
    <t>
     nsa_dup() is a wrapper around the dup() call, using a NEAT socket
     descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_dup(int oldfd)]]></artwork>
    <t>See the dup() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_lseek()</name>
    <t>
     nsa_lseek() is a wrapper around the lseek() call, using a NEAT socket
     descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
off_t nsa_lseek(int fd, off_t offset, int whence)]]></artwork>
    <t>See the lseek() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_lseek64()</name>
    <t>
     nsa_lseek64() is a wrapper around the lseek64() call, using a NEAT socket
     descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
off_t nsa_lseek(int fd, off64_t offset, int whence)]]></artwork>
    <t>See the lseek64() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_truncate()</name>
    <t>
     nsa_truncate() is a wrapper around the truncate() call, using a NEAT
     socket descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_ftruncate(int fd, off_t length)]]></artwork>
    <t>See the truncate() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_truncate64()</name>
    <t>
     nsa_truncate64() is a wrapper around the truncate64() call, using a NEAT
     socket descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_ftruncate(int fd, off64_t length)]]></artwork>
    <t>See the truncate64() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_pipe()</name>
    <t>
     nsa_pipe() is a wrapper around the pipe() call, returning NEAT socket
     descriptors instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_pipe(int fds[2])]]></artwork>
    <t>See the pipe() documentation for details.</t>
   </section>
   <section numbered="true" toc="default">
    <name>nsa_ioctl()</name>
    <t>
     nsa_ioctl() is a wrapper around the ioctl() call, using a NEAT socket
     descriptor instead.
    </t>
    <t>Function Prototype:</t>
    <artwork name="" type="" align="left" alt=""><![CDATA[
int nsa_ioctl(int fd, int request, const void* argp)]]></artwork>
    <t>See the ioctl() documentation for details.</t>
   </section>
  </section>
  <section numbered="true" toc="default">
   <name>Code Examples</name>
   <t>
    Running code examples can be found in the NEAT Git repository, with some
    tutorial material in <xref target="Haikou2017-2-NEAT-Tutorial" />,
    <xref target="Haikou2017-NEAT" />:
   </t>
   <dl newline="false" spacing="normal">
    <dt />
    <dd>
     URL:
     <eref target="https://github.com/NEAT-project/neat">https://github.com/NEAT-project/neat</eref>
    </dd>
    <dt />
    <dd>
     Branch:
     <eref target="https://github.com/NEAT-project/neat/tree/dreibh/neat-socketapi">dreibh/neat-socketapi</eref>
    </dd>
    <dt />
    <dd>
     Directory:
     <eref target="https://github.com/NEAT-project/neat/tree/dreibh/neat-socketapi/socketapi/examples">socketapi/examples/</eref>
    </dd>
   </dl>
  </section>
  <section numbered="true" toc="default">
   <name>Testbed Platform</name>
   <t>
    A large-scale and realistic Internet testbed platform with support for the
    multi-homing feature of the underlying SCTP and MPTCP protocols is NorNet.
    A description of NorNet is provided in <xref target="LinuxCon2016" />,
    <xref target="ComNets2013-Core" />, some further information can be found
    on the project website <xref target="NorNet-Website" />.
   </t>
  </section>
  <section numbered="true" toc="default">
   <name>Security Considerations</name>
   <t>
    Security considerations for the SCTP sockets API are described in
    <xref target="RFC6458" />.
   </t>
  </section>
  <section numbered="true" toc="default">
   <name>IANA Considerations</name>
   <t>This document does not require IANA actions.</t>
  </section>
  <section numbered="true" toc="default">
   <name>Acknowledgments</name>
   <t>
    This work was partially funded by the European Union's Horizon 2020
    research and innovation programme under grant agreement No. 644334 (NEAT).
    The views expressed are solely those of the author(s).
   </t>
   <t>
    The author would like to thank David Ros, Michael Welzl, and Xing Zhou for
    their support.
   </t>
  </section>
 </middle>
 <back>
  <references>
   <name>Normative References</name>
   <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml" />
   <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml" />
   <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6458.xml" />
   <xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.gjessing-taps-minset.xml" />
   <xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.fairhurst-taps-neat.xml" />
   <xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-taps-transports-usage.xml" />
  </references>
  <references>
   <name>Informative References</name>
   <reference anchor="LinuxCon2016" target="https://web-backend.simula.no/sites/default/files/publications/files/linuxcon2016-presentation.pdf">
    <front>
     <title>NorNet – Building an Inter-Continental Internet Testbed based on Open Source Software</title>
     <author initials="T." surname="Dreibholz" fullname="Thomas&nbsp;Dreibholz" />
     <date day="5" month="October" year="2016" />
    </front>
    <seriesInfo name="" value="Proceedings of the LinuxCon Europe" />
   </reference>
   <reference anchor="ComNets2013-Core" target="https://web-backend.simula.no/sites/default/files/publications/Simula.simula.2236.pdf">
    <front>
     <title>NorNet Core – A Multi-Homed Research Testbed</title>
     <author initials="E.&nbsp;G." surname="Gran" fullname="Ernst Gunnar&nbsp;Gran" />
     <author initials="T." surname="Dreibholz" fullname="Thomas&nbsp;Dreibholz" />
     <author initials="A." surname="Kvalbein" fullname="Amund&nbsp;Kvalbein" />
     <date day="14" month="March" year="2014" />
    </front>
    <seriesInfo name="Computer Networks, Special Issue on Future Internet Testbeds" value="Volume 61, Pages 75–87, ISSN&nbsp;1389-1286, DOI&nbsp;10.1016/j.bjp.2013.12.035" />
   </reference>
   <reference anchor="NEAT-Website" target="https://neat.nntb.no/">
    <front>
     <title>NEAT – A New, Evolutive API and Transport-Layer Architecture for the Internet</title>
     <author initials="T." surname="Dreibholz" fullname="Thomas Dreibholz" />
     <date year="2026" month="September" day="16" />
    </front>
   </reference>
   <reference anchor="NorNet-Website" target="https://www.nntb.no/">
    <front>
     <title>NorNet – A Real-World, Large-Scale Multi-Homing Testbed</title>
     <author initials="T." surname="Dreibholz" fullname="Thomas Dreibholz" />
     <date year="2026" month="September" day="16" />
    </front>
   </reference>
   <reference anchor="Haikou2017-2-NEAT-Tutorial" target="https://web-backend.simula.no/sites/default/files/publications/files/haikou2017-neat-tutorial.pdf">
    <front>
     <title>NEAT Tutorial at Hainan University: Getting Started with NEAT</title>
     <author initials="T." surname="Dreibholz" fullname="Thomas&nbsp;Dreibholz" />
     <date day="18" month="December" year="2017" />
    </front>
    <seriesInfo name="" value="Invited Talk at Hainan University, College of Information Science and Technology&nbsp;(CIST)" />
   </reference>
   <reference anchor="Haikou2017-NEAT" target="https://web-backend.simula.no/sites/default/files/publications/files/haikou2017-neat-introduction.pdf">
    <front>
     <title>A Practical Introduction to NEAT at Hainan University</title>
     <author initials="T." surname="Dreibholz" fullname="Thomas&nbsp;Dreibholz" />
     <date day="17" month="April" year="2017" />
    </front>
    <seriesInfo name="" value="Invited Talk at Hainan University, College of Information Science and Technology&nbsp;(CIST)" />
   </reference>
   <reference anchor="ANRW2017" target="https://web-backend.simula.no/sites/default/files/publications/files/anrw17-final13.pdf">
    <front>
     <title>A NEAT Way to Browse the Web</title>
     <author initials="F." surname="Weinrank" fullname="Felix&nbsp;Weinrank" />
     <author initials="K." surname="Grinnemo" fullname="Karl-Johan&nbsp;Grinnemo" />
     <author initials="Z." surname="Bozakov" fullname="Zdravko&nbsp;Bozakov" />
     <author initials="A." surname="Brunström" fullname="Anna&nbsp;Brunström" />
     <author initials="T." surname="Dreibholz" fullname="Thomas&nbsp;Dreibholz" />
     <author initials="P." surname="Hurtig" fullname="Per&nbsp;Hurtig" />
     <author initials="N." surname="Khademi" fullname="Naeem&nbsp;Khademi" />
     <author initials="M." surname="Tüxen" fullname="Michael&nbsp;Tüxen" />
     <date day="15" month="July" year="2017" />
    </front>
    <seriesInfo name="Proceedings of the ACM, IRTF and ISOC Applied Networking Research Workshop&nbsp;(ANRW)" value="Pages 33–34, ISBN&nbsp;978-1-4503-5108-9, DOI&nbsp;10.1145/3106328.3106335" />
   </reference>
   <reference anchor="NEAT-D1.1" target="https://neat.nntb.no/wp-content/uploads/2016/02/D1.1.pdf">
    <front>
     <title>NEAT Architecture</title>
     <author initials="G." surname="Fairhurst" fullname="Gorry&nbsp;Fairhurst" />
     <author initials="T." surname="Jones" fullname="Tom&nbsp;Jones" />
     <author initials="Z." surname="Bozakov" fullname="Zdravko&nbsp;Bozakov" />
     <author initials="A." surname="Brunström" fullname="Anna&nbsp;Brunström" />
     <author initials="D." surname="Damjanović" fullname="Dragana&nbsp;Damjanović" />
     <author initials="K.&nbsp;R.&nbsp;E.&nbsp;T." surname="Eckert" fullname="Kristian Riktor Evensen Toerless&nbsp;Eckert" />
     <author initials="K." surname="Grinnemo" fullname="Karl-Johan&nbsp;Grinnemo" />
     <author initials="A.&nbsp;F." surname="Hansen" fullname="Audun Fosselie&nbsp;Hansen" />
     <author initials="N." surname="Khademi" fullname="Naeem&nbsp;Khademi" />
     <author initials="S." surname="Mangiante" fullname="Simone&nbsp;Mangiante" />
     <author initials="P." surname="McManus" fullname="Patrick&nbsp;McManus" />
     <author initials="G." surname="Papastergiou" fullname="Giorgos&nbsp;Papastergiou" />
     <author initials="D." surname="Ros" fullname="David&nbsp;Ros" />
     <author initials="M." surname="Tüxen" fullname="Michael&nbsp;Tüxen" />
     <author initials="E." surname="Vyncke" fullname="Eric&nbsp;Vyncke" />
     <author initials="M." surname="Welzl" fullname="Michael&nbsp;Welzl" />
     <date day="1" month="December" year="2015" />
    </front>
    <seriesInfo name="" value="Number D1.1" />
   </reference>
   <reference anchor="NEAT-D1.3" target="https://neat.nntb.no/wp-content/uploads/2015/05/D1.3.pdf">
    <front>
     <title>Final Version of Services and APIs</title>
     <author initials="M." surname="Welzl" fullname="Michael&nbsp;Welzl" />
     <author initials="D." surname="Damjanović" fullname="Dragana&nbsp;Damjanović" />
     <author initials="G." surname="Fairhurst" fullname="Gorry&nbsp;Fairhurst" />
     <author initials="D." surname="Hayes" fullname="David&nbsp;Hayes" />
     <author initials="T." surname="Jones" fullname="Tom&nbsp;Jones" />
     <author initials="D." surname="Ros" fullname="David&nbsp;Ros" />
     <author initials="M." surname="Tüxen" fullname="Michael&nbsp;Tüxen" />
     <author initials="F." surname="Weinrank" fullname="Felix&nbsp;Weinrank" />
     <date day="30" month="October" year="2017" />
    </front>
    <seriesInfo name="Deliverable" value="D1.3" />
   </reference>
   <reference anchor="NEAT-D2.2" target="https://neat.nntb.no/wp-content/uploads/2017/03/D2.2-public.pdf">
    <front>
     <title>NEAT – Core Transport System, with both Low-level and High-level Components</title>
     <author initials="N." surname="Khademi" fullname="Naeem&nbsp;Khademi" />
     <author initials="Z." surname="Bozakov" fullname="Zdravko&nbsp;Bozakov" />
     <author initials="A." surname="Brunström" fullname="Anna&nbsp;Brunström" />
     <author initials="Ø." surname="Dale" fullname="Øystein&nbsp;Dale" />
     <author initials="D." surname="Damjanović" fullname="Dragana&nbsp;Damjanović" />
     <author initials="K.&nbsp;R." surname="Evensen" fullname="Kristian Riktor&nbsp;Evensen" />
     <author initials="G." surname="Fairhurst" fullname="Gorry&nbsp;Fairhurst" />
     <author initials="K." surname="Grinnemo" fullname="Karl-Johan&nbsp;Grinnemo" />
     <author initials="T." surname="Jones" fullname="Tom&nbsp;Jones" />
     <author initials="S." surname="Mangiante" fullname="Simone&nbsp;Mangiante" />
     <author initials="A." surname="Petlund" fullname="Andreas&nbsp;Petlund" />
     <author initials="D." surname="Ros" fullname="David&nbsp;Ros" />
     <author initials="D." surname="Stenberg" fullname="Daniel&nbsp;Stenberg" />
     <author initials="M." surname="Tüxen" fullname="Michael&nbsp;Tüxen" />
     <author initials="F." surname="Weinrank" fullname="Felix&nbsp;Weinrank" />
     <author initials="M." surname="Welzl" fullname="Michael&nbsp;Welzl" />
     <date day="14" month="March" year="2017" />
    </front>
    <seriesInfo name="" value="Number D2.2" />
   </reference>
   <reference anchor="NEAT-D2.3" target="https://neat.nntb.no/wp-content/uploads/2017/10/D2.3.pdf">
    <front>
     <title>Final Version of Core Transport System</title>
     <author initials="N." surname="Khademi" fullname="Naeem&nbsp;Khademi" />
     <author initials="Z." surname="Bozakov" fullname="Zdravko&nbsp;Bozakov" />
     <author initials="A." surname="Brunström" fullname="Anna&nbsp;Brunström" />
     <author initials="Ø." surname="Dale" fullname="Øystein&nbsp;Dale" />
     <author initials="D." surname="Damjanović" fullname="Dragana&nbsp;Damjanović" />
     <author initials="K.&nbsp;R." surname="Evensen" fullname="Kristian Riktor&nbsp;Evensen" />
     <author initials="G." surname="Fairhurst" fullname="Gorry&nbsp;Fairhurst" />
     <author initials="A." surname="Fischer" fullname="Andreas&nbsp;Fischer" />
     <author initials="K." surname="Grinnemo" fullname="Karl-Johan&nbsp;Grinnemo" />
     <author initials="T." surname="Jones" fullname="Tom&nbsp;Jones" />
     <author initials="S." surname="Mangiante" fullname="Simone&nbsp;Mangiante" />
     <author initials="A." surname="Petlund" fullname="Andreas&nbsp;Petlund" />
     <author initials="D." surname="Ros" fullname="David&nbsp;Ros" />
     <author initials="I." surname="Rüngeler" fullname="Irene&nbsp;Rüngeler" />
     <author initials="D." surname="Stenberg" fullname="Daniel&nbsp;Stenberg" />
     <author initials="M." surname="Tüxen" fullname="Michael&nbsp;Tüxen" />
     <author initials="F." surname="Weinrank" fullname="Felix&nbsp;Weinrank" />
     <author initials="M." surname="Welzl" fullname="Michael&nbsp;Welzl" />
     <date day="31" month="August" year="2017" />
    </front>
    <seriesInfo name="Deliverable" value="D2.3" />
   </reference>
  </references>
 </back>
</rfc>
