OSSP CVS Repository

ossp - ossp-pkg/sa/sa.pod 1.31
Not logged in
[Honeypot]  [Browse]  [Directory]  [Home]  [Login
[Reports]  [Search]  [Ticket]  [Timeline
  [Raw

ossp-pkg/sa/sa.pod 1.31
##
##  OSSP sa - Socket Abstraction
##  Copyright (c) 2001-2002 Ralf S. Engelschall <rse@engelschall.com>
##  Copyright (c) 2001-2002 The OSSP Project <http://www.ossp.org/>
##  Copyright (c) 2001-2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
##
##  This file is part of OSSP sa, a socket abstraction library which
##  can be found at http://www.ossp.org/pkg/lib/sa/.
##
##  Permission to use, copy, modify, and distribute this software for
##  any purpose with or without fee is hereby granted, provided that
##  the above copyright notice and this permission notice appear in all
##  copies.
##
##  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
##  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
##  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
##  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
##  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
##  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
##  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
##  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
##  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
##  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
##  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
##  SUCH DAMAGE.
##
##  sa.pod: socket abstraction library manual page
##

=pod

=head1 NAME

B<OSSP sa> - Socket Abstraction

=head1 VERSION

B<OSSP sa SA_VERSION_STR>

=head1 SYNOPSIS

=over 4

=item B<Abstract Data Types>:

sa_rc_t,
sa_addr_t,
sa_t.

=item B<Address Object Operations>:

sa_addr_create,
sa_addr_destroy.

=item B<Address Operations>:

sa_addr_u2a,
sa_addr_s2a,
sa_addr_a2u,
sa_addr_a2s,
sa_addr_match.

=item B<Socket Object Operations>:

sa_create,
sa_destroy.

=item B<Socket Parameter Operations>:

sa_type,
sa_timeout,
sa_buffer,
sa_option,
sa_syscall.

=item B<Socket Connection Operations>:

sa_bind,
sa_connect,
sa_listen,
sa_accept,
sa_getremote,
sa_getlocal,
sa_shutdown.

=item B<Socket Input/Output Operations (Stream Communication)>:

sa_getfd,
sa_read,
sa_readln,
sa_write,
sa_writef,
sa_flush.

=item B<Socket Input/Output Operations (Datagram Communication)>:

sa_recv,
sa_send.

=item B<Socket Error Handling>:

sa_error.

=back

=head1 DESCRIPTION

B<OSSP sa> is an abstraction library for the Unix I<Socket> networking
application programming interface (API), featuring stream and datagram
oriented communication over I<Unix Domain> and I<Internet Domain> (TCP
and UDP) sockets.

It provides the following key features:

=over 4

=item B<Stand-Alone, Self-Contained, Embeddable>

Although there are various Open Source libraries available which provide
a similar abstraction approach, they all either lack important features
or unfortunately depend on other companion libraries. B<OSSP sa> fills
this gap by providing all important features (see following points) as a
stand-alone and fully self-contained library. This way B<OSSP sa> can be
trivially embedded as a sub-library into other libraries. It especially
provides additional support for namespace-safe embedding of its API in
order to avoid symbol conflicts (see C<SA_PREFIX> in F<sa.h>).

=item B<Address Abstraction>

Most of the ugliness in the Unix I<Socket> API is the necessity to
have to deal with the various address structures (C<struct sockaddr_xx>)
which exist because of both the different communication types and
addressing schemes. B<OSSP sa> fully hides this by providing an abstract
and opaque address type (C<sa_addr_t>) together with utility functions
which allow one to convert from the traditional C<struct sockaddr> or
URI specification to the C<sa_addr_t> and vice versa without having to
deal with special cases related to the underlying particular C<struct
sockaddr_xx>. B<OSSP sa> support I<Unix Domain> and both IPv4 and IPv6
I<Internet Domain> addressing.

=item B<Type Abstraction>

Some other subtle details in the Unix I<Socket> API make the life hard
in practice: C<socklen_t> and C<ssize_t>. These two types originally
were (and on some platforms still are) plain integers or unsigned
integers while POSIX later introduced own types for them (and even
revised these types after some time again). This is nasty, because
for 100% type-correct API usage (especially important on 64-bit
machines where pointers to different integer types make trouble), every
application has to check whether the newer types exists, and if not
provide own definitions which map to the still actually used integer
type on the underlying platform. B<OSSP sa> hides most of this in its
API and for C<socklen_t> provides a backward-compatibility definition.
Instead of C<ssize_t> it can use C<size_t> because B<OSSP sa> does not use
traditional Unix return code semantics.

=item B<I/O Timeouts>

Each I/O function in B<OSSP sa> is aware of timeouts (set by
sa_timeout(3)), i.e., all I/O operations return C<SA_ERR_TMT> if
the timeout expired before the I/O operation was able to succeed.
This allows one to easily program less-blocking network services.
B<OSSP sa> internally implements these timeouts either through the
C<SO_>{C<SND>,C<RCV>}C<TIMEO> feature on more modern I<Socket>
implementations or through traditional select(2). This way high
performance is achieved on modern platforms while the full functionality
still is available on older platforms.

=item B<I/O Stream Buffering>

If B<OSSP sa> is used for stream communication, internally all I/O
operations can be performed through input and/or output buffers (set
by sa_buffer(3)) for achieving higher I/O performance by doing I/O
operations on larger aggregated messages and with less required system
calls. Additionally if B<OSSP sa> is used for stream communication, for
convenience reasons line-oriented reading (sa_readln(3)) and formatted
writing (see sa_writef(3)) is provided, modelled after STDIO's fgets(3)
and fprintf(3). Both features fully leverage from the I/O buffering.

=back

=head1 DATA TYPES

B<OSSP sa> uses three data types in its API:

=over 4

=item B<sa_rc_t> (Return Code Type)

This is an exported enumerated integer type with the following possible
values:

 SA_OK       Everything Ok
 SA_ERR_ARG  Invalid Argument
 SA_ERR_USE  Invalid Use Or Context
 SA_ERR_MEM  Not Enough Memory
 SA_ERR_MTC  Matching Failed
 SA_ERR_EOF  End Of Communication
 SA_ERR_TMT  Communication Timeout
 SA_ERR_SYS  Operating System Error (see errno)
 SA_ERR_IMP  Implementation Not Available
 SA_ERR_INT  Internal Error

=item B<sa_addr_t> (Socket Address Abstraction Type)

This is an opaque data type representing a socket address.
Only pointers to this abstract data type are used in the API.

=item B<sa_t> (Socket Abstraction Type)

This is an opaque data type representing a socket.
Only pointers to this abstract data type are used in the API.

=back

=head1 FUNCTIONS

B<OSSP sa> provides a bunch of API functions, all modelled after the
same prototype:

C<sa_rc_t> B<sa_>I<name>C<(sa_>[C<addr_>]C<_t *,> ...C<)>

This means, every function returns C<sa_rc_t> to indicate its success
(C<SA_OK>) or failure (C<SA_ERR_>I<XXX>) by returning a return code (the
corresponding describing text can be determined by passing this return
code to sa_error(3)). Each function name starts with the common prefix
C<sa_> and receives a C<sa_t> (or C<sa_addr_t>) object handle on which
it operates as its first argument.

=head2 Address Object Operations

This API part provides operations for the creation and destruction of
address abstraction C<sa_addr_t>.

=over 4

=item C<sa_rc_t >B<sa_addr_create>C<(sa_addr_t **>I<saa>C<);>

Create a socket address abstraction object.
The object is stored in I<saa> on success.

Example: C<sa_addr_t *saa; sa_addr_create(&saa);>

=item C<sa_rc_t >B<sa_addr_destroy>C<(sa_addr_t *>I<saa>C<);>

Destroy a socket address abstraction object.
The object I<saa> is invalid after this call succeeded.

Example: C<sa_addr_destroy(saa);>

=back

=head2 Address Operations

This API part provides operations for working with the address
abstraction C<sa_addr_t>.

=over 4

=item C<sa_rc_t >B<sa_addr_u2a>C<(sa_addr_t *>I<saa>C<, const char *>I<uri>C<, ...);>

Import an address into by converting from an URI specification to the
corresponding address abstraction.

The supported syntax for I<uri> is: "C<unix:>I<path>" for I<Unix Domain>
addresses and "C<inet://>I<addr>C<:>I<port>[C<#>I<protocol>]" for
I<Internet Domain> addresses.

In the URI, I<path> can be an absolute or relative filesystem path
to an existing or not-existing file. I<addr> can be an IPv4 address
in dotted decimal notation ("C<127.0.0.1>"), an IPv6 address in
colon-separated (optionally abbreviated) hexadecimal notation ("C<::1>")
or a to-be-resolved hostname ("C<localhost.example.com>"). I<port> has
to be either a decimal port in the range C<1>...C<65535> or a port name
("C<smtp>"). If I<port> is specified as a name, it is resolved as a TCP
port by default. To force resolving a I<port> name via a particular
protocol, I<protocol> can be specified as either "C<tcp>" or "C<udp>".

The result is stored in I<saa> on success.

Example: C<sa_addr_u2a(saa, "inet://192.168.0.1:smtp");>

=item C<sa_rc_t >B<sa_addr_s2a>C<(sa_addr_t *>I<saa>C<, const struct sockaddr *>I<sabuf>C<, socklen_t >I<salen>C<);>

Import an address by converting from a traditional C<struct sockaddr>
object to the corresponding address abstraction.

The accepted addresses for I<sabuf> are: C<struct sockaddr_un>
(C<AF_LOCAL>), C<struct sockaddr_in> (C<AF_INET>) and C<struct
sockaddr_in6> (C<AF_INET6>). The I<salen> is the corresponding
C<sizeof(...)> of the particular underyling structure.

The result is stored in I<saa> on success.

Example: C<sockaddr_in in; sa_addr_s2a(saa, (struct sockaddr *)&in, (socklen_t)sizeof(in));>

=item C<sa_rc_t >B<sa_addr_a2u>C<(sa_addr_t *>I<saa>C<, char **>I<uri>C<);>

Export an address by converting from the address abstraction to the
corresponding URI specification.

The result is a string of the form "C<unix:>I<path>" for I<Unix
Domain> addresses and "C<inet://>I<addr>C<:>I<port>" for I<Internet
Domain> addresses. Notice that I<addr> and I<port> are returned in
numerical (unresolved) way. Additionally, because usually one cannot map
bidirectionally between TCP or UDP port names and the numerical value,
there is no distinction between TCP and UDP here.

The result is stored in I<uri> on success.
The caller has to free(3) the I<uri> buffer later.

Example: C<char *uri; sa_addr_a2u(saa, &uri);>

=item C<sa_rc_t >B<sa_addr_a2s>C<(sa_addr_t *>I<saa>C<, struct sockaddr **>I<sabuf>C<, socklen_t *>I<salen>C<);>

Export an address by converting from the address abstraction to the
corresponding traditional C<struct sockaddr> object.

The result is one of the following particular underlying address
structures: C<struct sockaddr_un> (C<AF_LOCAL>), C<struct sockaddr_in>
(C<AF_INET>) and C<struct sockaddr_in6> (C<AF_INET6>).

The result is stored in I<sabuf> and I<salen> on success.
The caller has to free(3) the I<sabuf> buffer later.

Example: C<struct sockaddr sabuf, socklen_t salen; sa_addr_a2s(saa, &sa, &salen);>

=item C<sa_rc_t >B<sa_addr_match>C<(sa_addr_t *>I<saa1>C<, sa_addr_t *>I<saa2>C<, size_t >I<prefixlen>C<);>

Match two address abstractions up to a specified prefix.

This compares the addresses I<saa1> and I<saa2> by only taking the
prefix part of length I<prefixlen> into account. I<prefixlen> is number
of filesystem path characters for I<Unix Domain> addresses and number
of bits for I<Internet Domain> addresses. In case of I<Internet Domain>
addresses, the addresses are matched in network byte order and the port
(counting as an additional bit/item of length 1) is virtually appended
to the address for matching. Specifying I<prefixlen> as C<-1> means
matching the whole address (but without the virtually appended port)
without having to know how long the underlying address representation
(length of path for Unix Domain addresses, 32+1 [IPv4] or 128+1 [IPv6]
for Internet Domain addresses) is. Specifying I<prefixlen> as C<-2> is
equal to C<-1> but additionally the port is matched, too.

This especially can be used to implement Access Control Lists (ACL)
without having to fiddle around with the underlying representation.
For this, make I<saa1> the to be checked address and I<saa2> plus
I<prefixlen> the ACL pattern as shown in the following example.

Example:

 sa_addr_t *srv_sa;
 sa_addr_t *clt_saa;
 sa_t      *clt_sa;
 sa_addr_t *acl_saa;
 char      *acl_addr = "192.168.0.0";
 int        acl_len  = 24;
 ...
 sa_addr_u2a(&acl_saa, "inet://%s:0", acl_addr);
 ...
 while (sa_accept(srv_sa, &clt_saa, &clt_sa) == SA_OK) {
     if (sa_addr_match(clt_saa, acl_saa, acl_len) != SA_OK) {
         /* connection refused */
         ...
         sa_addr_destroy(clt_saa);
         sa_destroy(clt_sa);
         continue;
     }
     ...
 }
 ...

=back

=head2 Socket Object Operations

This API part provides operations for the creation and destruction of
socket abstraction C<sa_t>.

=over 4

=item C<sa_rc_t >B<sa_create>C<(sa_t **>I<sa>C<);>

Create a socket abstraction object.
The object is stored in I<sa> on success.

Example: C<sa_t *sa; sa_create(&sa);>

=item C<sa_rc_t >B<sa_destroy>C<(sa_t *>I<sa>C<);>

Destroy a socket abstraction object.
The object I<sa> is invalid after this call succeeded.

Example: C<sa_destroy(sa);>

=back

=head2 Socket Parameter Operations

This API part provides operations for parameterizing the socket
abstraction C<sa_t>.

=over 4

=item C<sa_rc_t >B<sa_type>C<(sa_t *>I<sa>C<, sa_type_t >I<type>C<);>

Assign a particular communication protocol type to the socket
abstraction object.

A socket can only be assigned a single protocol type at any time.
Nevertheless one can switch the type of a socket abstraction object at
any time in order to reuse it for a different communication. Just keep
in mind that switching the type will stop a still ongoing communication
by closing the underlying socket.

Possible values for I<type> are C<SA_TYPE_STREAM> (stream communication)
and C<SA_TYPE_DATAGRAM> (datagram communication). The default
communication protocol type is C<SA_TYPE_STREAM>.

Example: C<sa_type(sa, SA_TYPE_STREAM);>

=item C<sa_rc_t >B<sa_timeout>C<(sa_t *>I<sa>C<, sa_timeout_t >I<id>C<, long >I<sec>C<, long >I<usec>C<);>

Assign one or more communication timeouts to the socket abstraction
object.

Possible values for I<id> are: C<SA_TIMEOUT_ACCEPT> (affecting
sa_accept(3)), C<SA_TIMEOUT_CONNECT> (affecting sa_connect(3)),
C<SA_TIMEOUT_READ> (affecting sa_read(3), sa_readln(3) and sa_recv(3))
and C<SA_TIMEOUT_WRITE> (affecting sa_write(3), sa_writef(3) and
sa_send(3)). Additionally you can set all four timeouts at once by using
C<SA_TIMEOUT_ALL>. The default is that no communication timeouts are
used which is equal to I<sec>=C<0>/I<usec>=C<0>.

Example: C<sa_timeout(sa, SA_TIMEOUT_ALL, 30, 0);>

=item C<sa_rc_t >B<sa_buffer>C<(sa_t *>I<sa>C<, sa_buffer_t >I<id>C<, size_t >I<size>C<);>

Assign I/O communication buffers to the socket abstraction object.

Possible values for I<id> are: C<SA_BUFFER_READ> (affecting sa_read(3)
and sa_readln(3)) and C<SA_BUFFER_WRITE> (affecting sa_write(3) and
sa_writef(3)). The default is that no communication buffers are used
which is equal to I<size>=C<0>.

Example: C<sa_buffer(sa, SA_BUFFER_READ, 16384);>

=item C<sa_rc_t >B<sa_option>C<(sa_t *>I<sa>C<, sa_option_t >I<id>C<, ...);>

Adjust various options of the socket abstraction object.

The adjusted option is controlled by I<id>. The number and type of the
expected following argument(s) are dependent on the particular option.
Currently the following options are implemented (option arguments in
parenthesis):

C<SA_OPTION_NAGLE> (C<int> I<yesno>) for enabling (I<yesno>=C<1>) or
disabling (I<yesno> == C<0>) Nagle's Algorithm (see RFC898).

C<SA_OPTION_LINGER> (C<struct linger *>I<linger>) for enabling
(C<linger-E<gt>l_onoff> == C<1> and C<linger-E<gt>l_linger> ==
I<seconds>) or disabling (C<linger-E<gt>l_onoff> == C<0>) lingering
on close (see C<SO_LINGER> of setsockopt(2) and C<struct linger> in
F<sys/socket.h>).

C<SA_OPTION_REUSEADDR> (C<int> I<yesno>) for enabling (I<yesno> ==
C<1>) or disabling (I<yesno> == C<0>) the reusability of the address on
binding via sa_bind(3) (see C<SO_REUSEADDR> of setsockopt(2)).

C<SA_OPTION_REUSEPORT> (C<int> I<yesno>) for enabling (I<yesno> == C<1>)
or disabling (I<yesno> == C<0>) the reusability of the port on binding
via sa_bind(3) (see C<SO_REUSEPORT> of setsockopt(2)).

C<SA_OPTION_NONBLOCK> (C<int> I<yesno>) for enabling (I<yesno> == C<1>)
or disabling (I<yesno> == C<0>) non-blocking I/O mode (see C<O_NONBLOCK>
of fcntl(2)).

Example: C<sa_option(sa, SA_OPTION_NONBLOCK, 1);>

=item C<sa_rc_t >B<sa_syscall>C<(sa_t *>I<sa>C<, sa_syscall_t >I<id>C<, void (*>I<fptr>C<)(), void *>I<fctx>C<);>

Divert I/O communication related system calls to user supplied callback
functions.

This allows you to override mostly all I/O related system calls B<OSSP
sa> internally performs while communicating. This can be used to adapt
B<OSSP sa> to different run-time environments and requirements without
having to change the source code. Usually this is used to divert the
system calls to the variants of a user-land multithreading facility like
B<GNU Pth>.

The function supplied as I<fptr> is required to fulfill the API of
the replaced system call, i.e., it has to have the same prototype (if
I<fctx> is C<NULL>). If I<fctx> is not C<NULL>, this prototype has to be
extended to accept an additional first argument of type C<void *> which
receives the value of I<fctx>. It is up to the callback function whether
to pass the call through to the replaced actual system call or not.

Possible values for I<id> are (expected prototypes behind I<fptr> are
given in parenthesis):

C<SA_SYSCALL_CONNECT>: "C<int (*)([void *,] int, const struct sockaddr
*, socklen_t)>", see connect(2).

C<SA_SYSCALL_ACCEPT>: "C<int (*)([void *,] int, struct sockaddr *,
socklen_t *)>", see accept(2).

C<SA_SYSCALL_SELECT>: "C<int (*)([void *,] int, fd_set *, fd_set *,
fd_set *, struct timeval *)>", see select(2).

C<SA_SYSCALL_READ>: "C<ssize_t (*)([void *,] int, void *, size_t)>", see
read(2).

C<SA_SYSCALL_WRITE>: "C<ssize_t (*)([void *,] int, const void *,
size_t)>", see write(2).

C<SA_SYSCALL_RECVFROM>: "C<ssize_t (*)([void *,] int, void *, size_t,
int, struct sockaddr *, socklen_t *)>", see recvfrom(2).

C<SA_SYSCALL_SENDTO>: "C<ssize_t (*)([void *,] int, const void *,
size_t, int, const struct sockaddr *, socklen_t)>", see sendto(2).

Example:

 FILE *trace_fp = ...;

 ssize_t
 trace_read(void *ctx, int fd, void *buf, size_t len)
 {
     FILE *fp = (FILE *)ctx;
     ssize_t rv;
     int errno_saved;

     rv = read(fd, buf, len);
     errno_saved = errno;
     fprintf(fp, "read(%d, %lx, %d) = %d\n",
             fd, (long)buf, len, rv);
     errno = errno_saved;
     return rv;
 }

 sa_syscall(sa, SA_SC_READ, trace_read, trace_fp);

=back

=head2 Socket Connection Operations

This API part provides connection operations for stream-oriented data
communication through the socket abstraction C<sa_t>.

=over 4

=item C<sa_rc_t >B<sa_bind>C<(sa_t *>I<sa>C<, sa_addr_t *>I<laddr>C<);>

Bind socket abstraction object to a local protocol address.

This assigns the local protocol address I<laddr>. When a socket is
created, it exists in an address family space but has no protocol
address assigned. This call requests that I<laddr> be used as the local
address. For servers this is the address they later listen on (see
sa_listen(3)) for incoming connections, for clients this is the address
used for outgoing connections (see sa_connect(3)). Internally this
directly maps to bind(2).

Example: C<sa_bind(sa, laddr);>

=item C<sa_rc_t >B<sa_connect>C<(sa_t *>I<sa>C<, sa_addr_t *>I<raddr>C<);>

Initiate an outgoing connection on a socket abstraction object.

This performs a connect to the remote address I<raddr>. If the socket
is of type C<SA_TYPE_DATAGRAM>, this call specifies the peer with which
the socket is to be associated; this address is that to which datagrams
are to be sent, and the only address from which datagrams are to be
received. If the socket is of type C<SA_TYPE_STREAM>, this call attempts
to make a connection to the remote socket. Internally this directly maps
to connect(2).

Example: C<sa_connect(sa, raddr);>

=item C<sa_rc_t >B<sa_listen>C<(sa_t *>I<sa>C<, int >I<backlog>C<);>

Listen for incoming connections on a socket abstraction object.

A willingness to accept incoming connections and a queue limit for
incoming connections are specified by this call. The I<backlog> argument
defines the maximum length the queue of pending connections may grow to.
Internally this directly maps to listen(2).

Example: C<sa_listen(sa, 128);>

=item C<sa_rc_t >B<sa_accept>C<(sa_t *>I<sa>C<, sa_addr_t **>I<caddr>C<, sa_t **>I<csa>C<);>

Accept incoming connection on a socket abstraction object.

This accepts an incoming connection by extracting the first connection
request on the queue of pending connections. It creates a new socket
abstraction object (returned in I<csa>) and a new socket address
abstraction object (returned in I<caddr>) describing the connection. The
caller has to destroy these objects later. If no pending connections
are present on the queue, it blocks the caller until a connection is
present.

Example:

 sa_addr_t *clt_saa;
 sa_t      *clt_sa;
 ...
 while (sa_accept(srv_sa, &clt_saa, &clt_sa) == SA_OK) {
     ...
 }

=item C<sa_rc_t >B<sa_getremote>C<(sa_t *>I<sa>C<, sa_addr_t **>I<raddr>C<);>

Get address abstraction of remote side of communication.

This determines the address of the communication peer and creates a new
socket address abstraction object (returned in I<raddr>) describing
the peer address. The application has to destroy I<raddr> later with
sa_addr_destroy(3).

Example: C<sa_addr_t *raddr; sa_getremote(sa, &raddr);>

=item sa_rc_t B<sa_getlocal>(sa_t *I<sa>, sa_addr_t **I<laddr>);

Get address abstraction of local side of communication.

This determines the address of the local communication side and
creates a new socket address abstraction object (returned in I<laddr>)
describing the local address. The application has to destroy I<laddr>
later with sa_addr_destroy(3).

Example: C<sa_addr_t *laddr; sa_getlocal(sa, &laddr);>

=item sa_rc_t B<sa_shutdown>(sa_t *I<sa>, char *I<flags>);

Shut down part of the full-duplex connection.

This performs a shut down of the connection descriped in I<sa>. The
flags string can be either "C<r>" (indicating the read channel of the
communication is shut down only), "C<w>" (indicating the write channel
of the communication is shut down only), or "C<rw>" (indicating both the
read and write channels of the communication are shut down). Internally
this directly maps to shutdown(2).

Example: C<sa_shutdown(sa, "w");>

=back

=head2 Socket Input/Output Operations (Stream Communication)

This API part provides I/O operations for stream-oriented data
communication through the socket abstraction C<sa_t>.

=over 4

=item sa_rc_t B<sa_getfd>(sa_t *I<sa>, int *I<fd>);

Get underlying socket filedescriptor.

This peeks into the underlying socket filedescriptor B<OSSP sa>
allocated internally for the communication. This can be used for
adjusting the socket communication (via fcntl(2), setsockopt(2), etc)
directly.

Think twice before using this, then think once more. After all that,
think again. With enough thought, the need for directly manipulating the
underlying socket can often be eliminated. At least remember that all
your direct socket operations fully by-pass B<OSSP sa> and this way can
leads to nasty side-effects.

Example: C<int fd; sa_getfd(sa, &fd);>

=item sa_rc_t B<sa_read>(sa_t *I<sa>, char *I<buf>, size_t I<buflen>, size_t *I<bufdone>);

=item sa_rc_t B<sa_readln>(sa_t *I<sa>, char *I<buf>, size_t I<buflen>, size_t *I<bufdone>);

=item sa_rc_t B<sa_write>(sa_t *I<sa>, const char *I<buf>, size_t I<buflen>, size_t *I<bufdone>);

=item sa_rc_t B<sa_writef>(sa_t *I<sa>, const char *I<fmt>, ...);

=item sa_rc_t B<sa_flush>(sa_t *I<sa>);

=back

=head2 Socket Input/Output Operations (Datagram Communication)

This API part provides operations for datagram-oriented data
communication through the socket abstraction C<sa_t>.

=over 4

=item sa_rc_t B<sa_recv>(sa_t *I<sa>, char *I<buf>, size_t I<buflen>, size_t *I<bufdone>, sa_addr_t **I<raddr>);

=item sa_rc_t B<sa_send>(sa_t *I<sa>, const char *I<buf>, size_t I<buflen>, size_t *I<bufdone>, sa_addr_t *I<raddr>);

=back

=head2 Socket Error Handling

=over 4

=item char *B<sa_error>(sa_rc_t I<rv>);

=back

=head1 SEE ALSO

=head2 Standards

R. Gilligan, S. Thomson, J. Bound, W. Stevens:
"Basic Socket Interface Extensions for IPv6",
RFC 2553, March 1999.

W. Stevens:
"Advanced Sockets API for IPv6",
B<RFC 2292>, February 1998.

R. Fielding, L. Masinter, T. Berners-Lee:
"Uniform Resource Identifiers: Generic Syntax",
B<RFC 2396>, August 1998.

R. Hinden, S. Deering:
"IP Version 6 Addressing Architecture",
B<RFC 2373>, July 1998.

R. Hinden, B. Carpenter, L. Masinter:
"Format for Literal IPv6 Addresses in URL's",
B<RFC 2732>, December 1999.

=head2 Papers

Stuart Sechrest:
"An Introductory 4.4BSD Interprocess Communication Tutorial",
FreeBSD 4.4 (/usr/share/doc/psd/20.ipctut/).

Samuel J. Leffler, Robert S. Fabry, William N. Joy, Phil Lapsley:
"An Advanced 4.4BSD Interprocess Communication Tutorial",
FreeBSD 4.4 (/usr/share/doc/psd/21.ipc/).

Craig Metz:
"Protocol Independence Using the Sockets API"
http://www.usenix.org/publications/library/proceedings/usenix2000/freenix/metzprotocol.html,
USENIX Annual Technical Conference, June 2000.

=head2 Manual Pages

socket(2)
accept(2),
bind(2),
connect(2),
getpeername(2),
getsockname(2),
getsockopt(2),
ioctl(2),
listen(2),
read(2),
recv(2),
select(2),
send(2),
shutdown(2),
socketpair(2),
write(2),
getprotoent(3),
protocols(4)

=head1 HISTORY

B<OSSP sa> was invented in August 2001 by Ralf S. Engelschall
E<lt>rse@engelschall.comE<gt> for use inside the OSSP project. Its
creation was prompted by the requirement to implement an SMTP logging
channel for B<OSSP l2> (logging library). Its initial code was derived
from a predecessor sub-library originally written for socket address
abstraction inside B<OSSP lmtp2nntp>.

=head1 AUTHORS

 Ralf S. Engelschall
 rse@engelschall.com
 www.engelschall.com

=cut


CVSTrac 2.0.1