1
.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.14
4
.\" ========================================================================
5
.de Sh \" Subsection heading
13
.de Sp \" Vertical space (when we can't use .PP)
17
.de Vb \" Begin verbatim text
22
.de Ve \" End verbatim text
26
.\" Set up some character translations and predefined strings. \*(-- will
27
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
28
.\" double quote, and \*(R" will give a right double quote. | will give a
29
.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to
30
.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C'
31
.\" expand to `' in nroff, nothing in troff, for use with C<>.
33
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
37
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
38
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
51
.\" If the F register is turned on, we'll generate index entries on stderr for
52
.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
53
.\" entries marked with X<> in POD. Of course, you'll have to process the
54
.\" output yourself in some meaningful fashion.
57
. tm Index:\\$1\t\\n%\t"\\$2"
63
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
64
.\" way too many mistakes in technical documents.
68
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
69
.\" Fear. Run. Save yourself. No user-serviceable parts.
70
. \" fudge factors for nroff and troff
79
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
85
. \" simple accents for nroff and troff
95
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
96
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
97
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
98
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
99
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
100
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
102
. \" troff and (daisy-wheel) nroff accents
103
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
104
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
105
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
106
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
107
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
108
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
109
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
110
.ds ae a\h'-(\w'a'u*4/10)'e
111
.ds Ae A\h'-(\w'A'u*4/10)'E
112
. \" corrections for vroff
113
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
114
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
115
. \" for low resolution devices (crt and lpr)
116
.if \n(.H>23 .if \n(.V>19 \
129
.\" ========================================================================
132
.TH sa 3 "OSSP sa 1.2.2" "26-Jun-2004" "Socket Abstraction"
134
\&\fBOSSP sa\fR \- Socket Abstraction
137
\&\fB\s-1OSSP\s0 sa \s-11.2.2 (26-Jun-2004)\s0\fR
139
.IX Header "SYNOPSIS"
140
.IP "\fBAbstract Data Types\fR:" 4
141
.IX Item "Abstract Data Types:"
145
.IP "\fBAddress Object Operations\fR:" 4
146
.IX Item "Address Object Operations:"
149
.IP "\fBAddress Operations\fR:" 4
150
.IX Item "Address Operations:"
156
.IP "\fBSocket Object Operations\fR:" 4
157
.IX Item "Socket Object Operations:"
160
.IP "\fBSocket Parameter Operations\fR:" 4
161
.IX Item "Socket Parameter Operations:"
167
.IP "\fBSocket Connection Operations\fR:" 4
168
.IX Item "Socket Connection Operations:"
176
.IP "\fBSocket Input/Output Operations (Stream Communication)\fR:" 4
177
.IX Item "Socket Input/Output Operations (Stream Communication):"
184
.IP "\fBSocket Input/Output Operations (Datagram Communication)\fR:" 4
185
.IX Item "Socket Input/Output Operations (Datagram Communication):"
189
.IP "\fBSocket Error Handling\fR:" 4
190
.IX Item "Socket Error Handling:"
193
.IX Header "DESCRIPTION"
194
\&\fB\s-1OSSP\s0 sa\fR is an abstraction library for the Unix \fISocket\fR networking
195
application programming interface (\s-1API\s0), featuring stream and datagram
196
oriented communication over \fIUnix Domain\fR and \fIInternet Domain\fR (\s-1TCP\s0
197
and \s-1UDP\s0) sockets.
199
It provides the following key features:
200
.IP "\fBStand\-Alone, Self\-Contained, Embeddable\fR" 4
201
.IX Item "Stand-Alone, Self-Contained, Embeddable"
202
Although there are various Open Source libraries available which provide
203
a similar abstraction approach, they all either lack important features
204
or unfortunately depend on other companion libraries. \fB\s-1OSSP\s0 sa\fR fills
205
this gap by providing all important features (see following points) as a
206
stand-alone and fully self-contained library. This way \fB\s-1OSSP\s0 sa\fR can be
207
trivially embedded as a sub-library into other libraries. It especially
208
provides additional support for namespace-safe embedding of its \s-1API\s0 in
209
order to avoid symbol conflicts (see \f(CW\*(C`SA_PREFIX\*(C'\fR in \fIsa.h\fR).
210
.IP "\fBAddress Abstraction\fR" 4
211
.IX Item "Address Abstraction"
212
Most of the ugliness in the Unix \fISocket\fR \s-1API\s0 is the necessity to
213
have to deal with the various address structures (\f(CW\*(C`struct sockaddr_xx\*(C'\fR)
214
which exist because of both the different communication types and
215
addressing schemes. \fB\s-1OSSP\s0 sa\fR fully hides this by providing an abstract
216
and opaque address type (\f(CW\*(C`sa_addr_t\*(C'\fR) together with utility functions
217
which allow one to convert from the traditional \f(CW\*(C`struct sockaddr\*(C'\fR or
218
\&\s-1URI\s0 specification to the \f(CW\*(C`sa_addr_t\*(C'\fR and vice versa without having to
219
deal with special cases related to the underlying particular \f(CW\*(C`struct
220
sockaddr_xx\*(C'\fR. \fB\s-1OSSP\s0 sa\fR support \fIUnix Domain\fR and both IPv4 and IPv6
221
\&\fIInternet Domain\fR addressing.
222
.IP "\fBType Abstraction\fR" 4
223
.IX Item "Type Abstraction"
224
Some other subtle details in the Unix \fISocket\fR \s-1API\s0 make the life hard
225
in practice: \f(CW\*(C`socklen_t\*(C'\fR and \f(CW\*(C`ssize_t\*(C'\fR. These two types originally
226
were (and on some platforms still are) plain integers or unsigned
227
integers while \s-1POSIX\s0 later introduced own types for them (and even
228
revised these types after some time again). This is nasty, because
229
for 100% type-correct \s-1API\s0 usage (especially important on 64\-bit
230
machines where pointers to different integer types make trouble), every
231
application has to check whether the newer types exists, and if not
232
provide own definitions which map to the still actually used integer
233
type on the underlying platform. \fB\s-1OSSP\s0 sa\fR hides most of this in its
234
\&\s-1API\s0 and for \f(CW\*(C`socklen_t\*(C'\fR provides a backward-compatibility definition.
235
Instead of \f(CW\*(C`ssize_t\*(C'\fR it can use \f(CW\*(C`size_t\*(C'\fR because \fB\s-1OSSP\s0 sa\fR does not use
236
traditional Unix return code semantics.
237
.IP "\fBI/O Timeouts\fR" 4
238
.IX Item "I/O Timeouts"
239
Each I/O function in \fB\s-1OSSP\s0 sa\fR is aware of timeouts (set by
240
\&\fIsa_timeout\fR\|(3)), i.e., all I/O operations return \f(CW\*(C`SA_ERR_TMT\*(C'\fR if
241
the timeout expired before the I/O operation was able to succeed.
242
This allows one to easily program less-blocking network services.
243
\&\fB\s-1OSSP\s0 sa\fR internally implements these timeouts either through the
244
\&\f(CW\*(C`SO_\*(C'\fR{\f(CW\*(C`SND\*(C'\fR,\f(CW\*(C`RCV\*(C'\fR}\f(CW\*(C`TIMEO\*(C'\fR feature on more modern \fISocket\fR
245
implementations or through traditional \fIselect\fR\|(2). This way high
246
performance is achieved on modern platforms while the full functionality
247
still is available on older platforms.
248
.IP "\fBI/O Stream Buffering\fR" 4
249
.IX Item "I/O Stream Buffering"
250
If \fB\s-1OSSP\s0 sa\fR is used for stream communication, internally all I/O
251
operations can be performed through input and/or output buffers (set
252
by \fIsa_buffer\fR\|(3)) for achieving higher I/O performance by doing I/O
253
operations on larger aggregated messages and with less required system
254
calls. Additionally if \fB\s-1OSSP\s0 sa\fR is used for stream communication, for
255
convenience reasons line-oriented reading (\fIsa_readln\fR\|(3)) and formatted
256
writing (see \fIsa_writef\fR\|(3)) is provided, modelled after \s-1STDIO\s0's \fIfgets\fR\|(3)
257
and \fIfprintf\fR\|(3). Both features fully leverage from the I/O buffering.
259
.IX Header "DATA TYPES"
260
\&\fB\s-1OSSP\s0 sa\fR uses three data types in its \s-1API:\s0
261
.IP "\fBsa_rc_t\fR (Return Code Type)" 4
262
.IX Item "sa_rc_t (Return Code Type)"
263
This is an exported enumerated integer type with the following possible
267
\& SA_OK Everything Ok
268
\& SA_ERR_ARG Invalid Argument
269
\& SA_ERR_USE Invalid Use Or Context
270
\& SA_ERR_MEM Not Enough Memory
271
\& SA_ERR_MTC Matching Failed
272
\& SA_ERR_EOF End Of Communication
273
\& SA_ERR_TMT Communication Timeout
274
\& SA_ERR_SYS Operating System Error (see errno)
275
\& SA_ERR_IMP Implementation Not Available
276
\& SA_ERR_INT Internal Error
278
.IP "\fBsa_addr_t\fR (Socket Address Abstraction Type)" 4
279
.IX Item "sa_addr_t (Socket Address Abstraction Type)"
280
This is an opaque data type representing a socket address.
281
Only pointers to this abstract data type are used in the \s-1API\s0.
282
.IP "\fBsa_t\fR (Socket Abstraction Type)" 4
283
.IX Item "sa_t (Socket Abstraction Type)"
284
This is an opaque data type representing a socket.
285
Only pointers to this abstract data type are used in the \s-1API\s0.
287
.IX Header "FUNCTIONS"
288
\&\fB\s-1OSSP\s0 sa\fR provides a bunch of \s-1API\s0 functions, all modelled after the
291
\&\f(CW\*(C`sa_rc_t\*(C'\fR \fBsa_\fR\fIname\fR\f(CW\*(C`(sa_\*(C'\fR[\f(CW\*(C`addr_\*(C'\fR]\f(CW\*(C`_t *,\*(C'\fR ...\f(CW\*(C`)\*(C'\fR
293
This means, every function returns \f(CW\*(C`sa_rc_t\*(C'\fR to indicate its success
294
(\f(CW\*(C`SA_OK\*(C'\fR) or failure (\f(CW\*(C`SA_ERR_\*(C'\fR\fI\s-1XXX\s0\fR) by returning a return code (the
295
corresponding describing text can be determined by passing this return
296
code to \fIsa_error\fR\|(3)). Each function name starts with the common prefix
297
\&\f(CW\*(C`sa_\*(C'\fR and receives a \f(CW\*(C`sa_t\*(C'\fR (or \f(CW\*(C`sa_addr_t\*(C'\fR) object handle on which
298
it operates as its first argument.
299
.Sh "Address Object Operations"
300
.IX Subsection "Address Object Operations"
301
This \s-1API\s0 part provides operations for the creation and destruction of
302
address abstraction \f(CW\*(C`sa_addr_t\*(C'\fR.
303
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_addr_create\fR\f(CW\*(C`(sa_addr_t **\*(C'\fR\fIsaa\fR\f(CW\*(C`);\*(C'" 4
304
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_addr_create\fR\f(CW\*(C`(sa_addr_t **\*(C'\fR\fIsaa\fR\f(CW\*(C`);\*(C'\fR" 4
305
.IX Item "sa_rc_t sa_addr_create(sa_addr_t **saa);"
306
Create a socket address abstraction object.
307
The object is stored in \fIsaa\fR on success.
309
Example: \f(CW\*(C`sa_addr_t *saa; sa_addr_create(&saa);\*(C'\fR
310
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_addr_destroy\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa\fR\f(CW\*(C`);\*(C'" 4
311
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_addr_destroy\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa\fR\f(CW\*(C`);\*(C'\fR" 4
312
.IX Item "sa_rc_t sa_addr_destroy(sa_addr_t *saa);"
313
Destroy a socket address abstraction object.
314
The object \fIsaa\fR is invalid after this call succeeded.
316
Example: \f(CW\*(C`sa_addr_destroy(saa);\*(C'\fR
317
.Sh "Address Operations"
318
.IX Subsection "Address Operations"
319
This \s-1API\s0 part provides operations for working with the address
320
abstraction \f(CW\*(C`sa_addr_t\*(C'\fR.
321
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_addr_u2a\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa\fR\f(CW\*(C`, const char *\*(C'\fR\fIuri\fR\f(CW\*(C`, ...);\*(C'" 4
322
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_addr_u2a\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa\fR\f(CW\*(C`, const char *\*(C'\fR\fIuri\fR\f(CW\*(C`, ...);\*(C'\fR" 4
323
.IX Item "sa_rc_t sa_addr_u2a(sa_addr_t *saa, const char *uri, ...);"
324
Import an address into by converting from an \s-1URI\s0 specification to the
325
corresponding address abstraction.
327
The supported syntax for \fIuri\fR is: "\f(CW\*(C`unix:\*(C'\fR\fIpath\fR" for \fIUnix Domain\fR
328
addresses and "\f(CW\*(C`inet://\*(C'\fR\fIaddr\fR\f(CW\*(C`:\*(C'\fR\fIport\fR[\f(CW\*(C`#\*(C'\fR\fIprotocol\fR]" for
329
\&\fIInternet Domain\fR addresses.
331
In the \s-1URI\s0, \fIpath\fR can be an absolute or relative filesystem path
332
to an existing or not-existing file. \fIaddr\fR can be an IPv4 address
333
in dotted decimal notation ("\f(CW127.0.0.1\fR\*(L"), an IPv6 address in
334
colon-separated (optionally abbreviated) hexadecimal notation (\*(R"\f(CW\*(C`::1\*(C'\fR\*(L")
335
or a to-be-resolved hostname (\*(R"\f(CW\*(C`localhost.example.com\*(C'\fR"). \fIport\fR has
336
to be either a decimal port in the range \f(CW1\fR...\f(CW65535\fR or a port name
337
("\f(CW\*(C`smtp\*(C'\fR"). If \fIport\fR is specified as a name, it is resolved as a \s-1TCP\s0
338
port by default. To force resolving a \fIport\fR name via a particular
339
protocol, \fIprotocol\fR can be specified as either "\f(CW\*(C`tcp\*(C'\fR\*(L" or \*(R"\f(CW\*(C`udp\*(C'\fR".
341
The result is stored in \fIsaa\fR on success.
343
Example: \f(CW\*(C`sa_addr_u2a(saa, "inet://192.168.0.1:smtp");\*(C'\fR
344
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_addr_s2a\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa\fR\f(CW\*(C`, const struct sockaddr *\*(C'\fR\fIsabuf\fR\f(CW\*(C`, socklen_t \*(C'\fR\fIsalen\fR\f(CW\*(C`);\*(C'" 4
345
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_addr_s2a\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa\fR\f(CW\*(C`, const struct sockaddr *\*(C'\fR\fIsabuf\fR\f(CW\*(C`, socklen_t \*(C'\fR\fIsalen\fR\f(CW\*(C`);\*(C'\fR" 4
346
.IX Item "sa_rc_t sa_addr_s2a(sa_addr_t *saa, const struct sockaddr *sabuf, socklen_t salen);"
347
Import an address by converting from a traditional \f(CW\*(C`struct sockaddr\*(C'\fR
348
object to the corresponding address abstraction.
350
The accepted addresses for \fIsabuf\fR are: \f(CW\*(C`struct sockaddr_un\*(C'\fR
351
(\f(CW\*(C`AF_LOCAL\*(C'\fR), \f(CW\*(C`struct sockaddr_in\*(C'\fR (\f(CW\*(C`AF_INET\*(C'\fR) and \f(CW\*(C`struct
352
sockaddr_in6\*(C'\fR (\f(CW\*(C`AF_INET6\*(C'\fR). The \fIsalen\fR is the corresponding
353
\&\f(CW\*(C`sizeof(...)\*(C'\fR of the particular underyling structure.
355
The result is stored in \fIsaa\fR on success.
357
Example: \f(CW\*(C`sockaddr_in in; sa_addr_s2a(saa, (struct sockaddr *)&in, (socklen_t)sizeof(in));\*(C'\fR
358
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_addr_a2u\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa\fR\f(CW\*(C`, char **\*(C'\fR\fIuri\fR\f(CW\*(C`);\*(C'" 4
359
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_addr_a2u\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa\fR\f(CW\*(C`, char **\*(C'\fR\fIuri\fR\f(CW\*(C`);\*(C'\fR" 4
360
.IX Item "sa_rc_t sa_addr_a2u(sa_addr_t *saa, char **uri);"
361
Export an address by converting from the address abstraction to the
362
corresponding \s-1URI\s0 specification.
364
The result is a string of the form "\f(CW\*(C`unix:\*(C'\fR\fIpath\fR" for \fIUnix
365
Domain\fR addresses and "\f(CW\*(C`inet://\*(C'\fR\fIaddr\fR\f(CW\*(C`:\*(C'\fR\fIport\fR" for \fIInternet
366
Domain\fR addresses. Notice that \fIaddr\fR and \fIport\fR are returned in
367
numerical (unresolved) way. Additionally, because usually one cannot map
368
bidirectionally between \s-1TCP\s0 or \s-1UDP\s0 port names and the numerical value,
369
there is no distinction between \s-1TCP\s0 and \s-1UDP\s0 here.
371
The result is stored in \fIuri\fR on success.
372
The caller has to \fIfree\fR\|(3) the \fIuri\fR buffer later.
374
Example: \f(CW\*(C`char *uri; sa_addr_a2u(saa, &uri);\*(C'\fR
375
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_addr_a2s\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa\fR\f(CW\*(C`, struct sockaddr **\*(C'\fR\fIsabuf\fR\f(CW\*(C`, socklen_t *\*(C'\fR\fIsalen\fR\f(CW\*(C`);\*(C'" 4
376
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_addr_a2s\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa\fR\f(CW\*(C`, struct sockaddr **\*(C'\fR\fIsabuf\fR\f(CW\*(C`, socklen_t *\*(C'\fR\fIsalen\fR\f(CW\*(C`);\*(C'\fR" 4
377
.IX Item "sa_rc_t sa_addr_a2s(sa_addr_t *saa, struct sockaddr **sabuf, socklen_t *salen);"
378
Export an address by converting from the address abstraction to the
379
corresponding traditional \f(CW\*(C`struct sockaddr\*(C'\fR object.
381
The result is one of the following particular underlying address
382
structures: \f(CW\*(C`struct sockaddr_un\*(C'\fR (\f(CW\*(C`AF_LOCAL\*(C'\fR), \f(CW\*(C`struct sockaddr_in\*(C'\fR
383
(\f(CW\*(C`AF_INET\*(C'\fR) and \f(CW\*(C`struct sockaddr_in6\*(C'\fR (\f(CW\*(C`AF_INET6\*(C'\fR).
385
The result is stored in \fIsabuf\fR and \fIsalen\fR on success.
386
The caller has to \fIfree\fR\|(3) the \fIsabuf\fR buffer later.
388
Example: \f(CW\*(C`struct sockaddr sabuf, socklen_t salen; sa_addr_a2s(saa, &sa, &salen);\*(C'\fR
389
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_addr_match\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa1\fR\f(CW\*(C`, sa_addr_t *\*(C'\fR\fIsaa2\fR\f(CW\*(C`, size_t \*(C'\fR\fIprefixlen\fR\f(CW\*(C`);\*(C'" 4
390
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_addr_match\fR\f(CW\*(C`(sa_addr_t *\*(C'\fR\fIsaa1\fR\f(CW\*(C`, sa_addr_t *\*(C'\fR\fIsaa2\fR\f(CW\*(C`, size_t \*(C'\fR\fIprefixlen\fR\f(CW\*(C`);\*(C'\fR" 4
391
.IX Item "sa_rc_t sa_addr_match(sa_addr_t *saa1, sa_addr_t *saa2, size_t prefixlen);"
392
Match two address abstractions up to a specified prefix.
394
This compares the addresses \fIsaa1\fR and \fIsaa2\fR by only taking the
395
prefix part of length \fIprefixlen\fR into account. \fIprefixlen\fR is number
396
of filesystem path characters for \fIUnix Domain\fR addresses and number
397
of bits for \fIInternet Domain\fR addresses. In case of \fIInternet Domain\fR
398
addresses, the addresses are matched in network byte order and the port
399
(counting as an additional bit/item of length 1) is virtually appended
400
to the address for matching. Specifying \fIprefixlen\fR as \f(CW\*(C`\-1\*(C'\fR means
401
matching the whole address (but without the virtually appended port)
402
without having to know how long the underlying address representation
403
(length of path for Unix Domain addresses, 32+1 [IPv4] or 128+1 [IPv6]
404
for Internet Domain addresses) is. Specifying \fIprefixlen\fR as \f(CW\*(C`\-2\*(C'\fR is
405
equal to \f(CW\*(C`\-1\*(C'\fR but additionally the port is matched, too.
407
This especially can be used to implement Access Control Lists (\s-1ACL\s0)
408
without having to fiddle around with the underlying representation.
409
For this, make \fIsaa1\fR the to be checked address and \fIsaa2\fR plus
410
\&\fIprefixlen\fR the \s-1ACL\s0 pattern as shown in the following example.
415
\& sa_addr_t *srv_sa;
416
\& sa_addr_t *clt_saa;
418
\& sa_addr_t *acl_saa;
419
\& char *acl_addr = "192.168.0.0";
422
\& sa_addr_u2a(&acl_saa, "inet://%s:0", acl_addr);
424
\& while (sa_accept(srv_sa, &clt_saa, &clt_sa) == SA_OK) {
425
\& if (sa_addr_match(clt_saa, acl_saa, acl_len) != SA_OK) {
426
\& /* connection refused */
428
\& sa_addr_destroy(clt_saa);
429
\& sa_destroy(clt_sa);
436
.Sh "Socket Object Operations"
437
.IX Subsection "Socket Object Operations"
438
This \s-1API\s0 part provides operations for the creation and destruction of
439
socket abstraction \f(CW\*(C`sa_t\*(C'\fR.
440
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_create\fR\f(CW\*(C`(sa_t **\*(C'\fR\fIsa\fR\f(CW\*(C`);\*(C'" 4
441
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_create\fR\f(CW\*(C`(sa_t **\*(C'\fR\fIsa\fR\f(CW\*(C`);\*(C'\fR" 4
442
.IX Item "sa_rc_t sa_create(sa_t **sa);"
443
Create a socket abstraction object.
444
The object is stored in \fIsa\fR on success.
446
Example: \f(CW\*(C`sa_t *sa; sa_create(&sa);\*(C'\fR
447
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_destroy\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`);\*(C'" 4
448
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_destroy\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`);\*(C'\fR" 4
449
.IX Item "sa_rc_t sa_destroy(sa_t *sa);"
450
Destroy a socket abstraction object.
451
The object \fIsa\fR is invalid after this call succeeded.
453
Example: \f(CW\*(C`sa_destroy(sa);\*(C'\fR
454
.Sh "Socket Parameter Operations"
455
.IX Subsection "Socket Parameter Operations"
456
This \s-1API\s0 part provides operations for parameterizing the socket
457
abstraction \f(CW\*(C`sa_t\*(C'\fR.
458
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_type\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_type_t \*(C'\fR\fItype\fR\f(CW\*(C`);\*(C'" 4
459
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_type\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_type_t \*(C'\fR\fItype\fR\f(CW\*(C`);\*(C'\fR" 4
460
.IX Item "sa_rc_t sa_type(sa_t *sa, sa_type_t type);"
461
Assign a particular communication protocol type to the socket
464
A socket can only be assigned a single protocol type at any time.
465
Nevertheless one can switch the type of a socket abstraction object at
466
any time in order to reuse it for a different communication. Just keep
467
in mind that switching the type will stop a still ongoing communication
468
by closing the underlying socket.
470
Possible values for \fItype\fR are \f(CW\*(C`SA_TYPE_STREAM\*(C'\fR (stream communication)
471
and \f(CW\*(C`SA_TYPE_DATAGRAM\*(C'\fR (datagram communication). The default
472
communication protocol type is \f(CW\*(C`SA_TYPE_STREAM\*(C'\fR.
474
Example: \f(CW\*(C`sa_type(sa, SA_TYPE_STREAM);\*(C'\fR
475
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_timeout\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_timeout_t \*(C'\fR\fIid\fR\f(CW\*(C`, long \*(C'\fR\fIsec\fR\f(CW\*(C`, long \*(C'\fR\fIusec\fR\f(CW\*(C`);\*(C'" 4
476
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_timeout\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_timeout_t \*(C'\fR\fIid\fR\f(CW\*(C`, long \*(C'\fR\fIsec\fR\f(CW\*(C`, long \*(C'\fR\fIusec\fR\f(CW\*(C`);\*(C'\fR" 4
477
.IX Item "sa_rc_t sa_timeout(sa_t *sa, sa_timeout_t id, long sec, long usec);"
478
Assign one or more communication timeouts to the socket abstraction
481
Possible values for \fIid\fR are: \f(CW\*(C`SA_TIMEOUT_ACCEPT\*(C'\fR (affecting
482
\&\fIsa_accept\fR\|(3)), \f(CW\*(C`SA_TIMEOUT_CONNECT\*(C'\fR (affecting \fIsa_connect\fR\|(3)),
483
\&\f(CW\*(C`SA_TIMEOUT_READ\*(C'\fR (affecting \fIsa_read\fR\|(3), \fIsa_readln\fR\|(3) and \fIsa_recv\fR\|(3))
484
and \f(CW\*(C`SA_TIMEOUT_WRITE\*(C'\fR (affecting \fIsa_write\fR\|(3), \fIsa_writef\fR\|(3),
485
\&\fIsa_send\fR\|(3), and \fIsa_sendf\fR\|(3)). Additionally you can set all four timeouts
486
at once by using \f(CW\*(C`SA_TIMEOUT_ALL\*(C'\fR. The default is that no communication
487
timeouts are used which is equal to \fIsec\fR=\f(CW0\fR/\fIusec\fR=\f(CW0\fR.
489
Example: \f(CW\*(C`sa_timeout(sa, SA_TIMEOUT_ALL, 30, 0);\*(C'\fR
490
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_buffer\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_buffer_t \*(C'\fR\fIid\fR\f(CW\*(C`, size_t \*(C'\fR\fIsize\fR\f(CW\*(C`);\*(C'" 4
491
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_buffer\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_buffer_t \*(C'\fR\fIid\fR\f(CW\*(C`, size_t \*(C'\fR\fIsize\fR\f(CW\*(C`);\*(C'\fR" 4
492
.IX Item "sa_rc_t sa_buffer(sa_t *sa, sa_buffer_t id, size_t size);"
493
Assign I/O communication buffers to the socket abstraction object.
495
Possible values for \fIid\fR are: \f(CW\*(C`SA_BUFFER_READ\*(C'\fR (affecting \fIsa_read\fR\|(3)
496
and \fIsa_readln\fR\|(3)) and \f(CW\*(C`SA_BUFFER_WRITE\*(C'\fR (affecting \fIsa_write\fR\|(3) and
497
\&\fIsa_writef\fR\|(3)). The default is that no communication buffers are used
498
which is equal to \fIsize\fR=\f(CW0\fR.
500
Example: \f(CW\*(C`sa_buffer(sa, SA_BUFFER_READ, 16384);\*(C'\fR
501
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_option\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_option_t \*(C'\fR\fIid\fR\f(CW\*(C`, ...);\*(C'" 4
502
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_option\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_option_t \*(C'\fR\fIid\fR\f(CW\*(C`, ...);\*(C'\fR" 4
503
.IX Item "sa_rc_t sa_option(sa_t *sa, sa_option_t id, ...);"
504
Adjust various options of the socket abstraction object.
506
The adjusted option is controlled by \fIid\fR. The number and type of the
507
expected following argument(s) are dependent on the particular option.
508
Currently the following options are implemented (option arguments in
511
\&\f(CW\*(C`SA_OPTION_NAGLE\*(C'\fR (\f(CW\*(C`int\*(C'\fR \fIyesno\fR) for enabling (\fIyesno\fR=\f(CW1\fR)
512
or disabling (\fIyesno\fR == \f(CW0\fR) Nagle's Algorithm (see \s-1RFC898\s0 and
513
\&\f(CW\*(C`TCP_NODELAY\*(C'\fR of \fIsetsockopt\fR\|(2)).
515
\&\f(CW\*(C`SA_OPTION_LINGER\*(C'\fR (\f(CW\*(C`int\*(C'\fR \fIamount\fR) for enabling (\fIamount\fR ==
516
\&\fIseconds\fR != \f(CW0\fR) or disabling (\fIamount\fR == \f(CW0\fR) lingering on close
517
(see \f(CW\*(C`SO_LINGER\*(C'\fR of \fIsetsockopt\fR\|(2)). Notice: using \fIseconds\fR > \f(CW0\fR
518
results in a regular (maximum of \fIseconds\fR lasting) lingering on close
519
while using \fIseconds\fR < \f(CW0\fR results in the special case of a \s-1TCP\s0
520
\&\s-1RST\s0 based connection termination on close.
522
\&\f(CW\*(C`SA_OPTION_REUSEADDR\*(C'\fR (\f(CW\*(C`int\*(C'\fR \fIyesno\fR) for enabling (\fIyesno\fR ==
523
\&\f(CW1\fR) or disabling (\fIyesno\fR == \f(CW0\fR) the reusability of the address on
524
binding via \fIsa_bind\fR\|(3) (see \f(CW\*(C`SO_REUSEADDR\*(C'\fR of \fIsetsockopt\fR\|(2)).
526
\&\f(CW\*(C`SA_OPTION_REUSEPORT\*(C'\fR (\f(CW\*(C`int\*(C'\fR \fIyesno\fR) for enabling (\fIyesno\fR == \f(CW1\fR)
527
or disabling (\fIyesno\fR == \f(CW0\fR) the reusability of the port on binding
528
via \fIsa_bind\fR\|(3) (see \f(CW\*(C`SO_REUSEPORT\*(C'\fR of \fIsetsockopt\fR\|(2)).
530
\&\f(CW\*(C`SA_OPTION_NONBLOCK\*(C'\fR (\f(CW\*(C`int\*(C'\fR \fIyesno\fR) for enabling (\fIyesno\fR == \f(CW1\fR)
531
or disabling (\fIyesno\fR == \f(CW0\fR) non-blocking I/O mode (see \f(CW\*(C`O_NONBLOCK\*(C'\fR
532
of \fIfcntl\fR\|(2)).
534
Example: \f(CW\*(C`sa_option(sa, SA_OPTION_NONBLOCK, 1);\*(C'\fR
535
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_syscall\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_syscall_t \*(C'\fR\fIid\fR\f(CW\*(C`, void (*\*(C'\fR\fIfptr\fR\f(CW\*(C`)(), void *\*(C'\fR\fIfctx\fR\f(CW\*(C`);\*(C'" 4
536
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_syscall\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_syscall_t \*(C'\fR\fIid\fR\f(CW\*(C`, void (*\*(C'\fR\fIfptr\fR\f(CW\*(C`)(), void *\*(C'\fR\fIfctx\fR\f(CW\*(C`);\*(C'\fR" 4
537
.IX Item "sa_rc_t sa_syscall(sa_t *sa, sa_syscall_t id, void (*fptr)(), void *fctx);"
538
Divert I/O communication related system calls to user supplied callback
541
This allows you to override mostly all I/O related system calls \fB\s-1OSSP\s0
542
sa\fR internally performs while communicating. This can be used to adapt
543
\&\fB\s-1OSSP\s0 sa\fR to different run-time environments and requirements without
544
having to change the source code. Usually this is used to divert the
545
system calls to the variants of a user-land multithreading facility like
546
\&\fB\s-1GNU\s0 Pth\fR.
548
The function supplied as \fIfptr\fR is required to fulfill the \s-1API\s0 of
549
the replaced system call, i.e., it has to have the same prototype (if
550
\&\fIfctx\fR is \f(CW\*(C`NULL\*(C'\fR). If \fIfctx\fR is not \f(CW\*(C`NULL\*(C'\fR, this prototype has to be
551
extended to accept an additional first argument of type \f(CW\*(C`void *\*(C'\fR which
552
receives the value of \fIfctx\fR. It is up to the callback function whether
553
to pass the call through to the replaced actual system call or not.
555
Possible values for \fIid\fR are (expected prototypes behind \fIfptr\fR are
556
given in parenthesis):
558
\&\f(CW\*(C`SA_SYSCALL_CONNECT\*(C'\fR: "\f(CW\*(C`int (*)([void *,] int, const struct sockaddr
559
*, socklen_t)\*(C'\fR", see \fIconnect\fR\|(2).
561
\&\f(CW\*(C`SA_SYSCALL_ACCEPT\*(C'\fR: "\f(CW\*(C`int (*)([void *,] int, struct sockaddr *,
562
socklen_t *)\*(C'\fR", see \fIaccept\fR\|(2).
564
\&\f(CW\*(C`SA_SYSCALL_SELECT\*(C'\fR: "\f(CW\*(C`int (*)([void *,] int, fd_set *, fd_set *,
565
fd_set *, struct timeval *)\*(C'\fR", see \fIselect\fR\|(2).
567
\&\f(CW\*(C`SA_SYSCALL_READ\*(C'\fR: "\f(CW\*(C`ssize_t (*)([void *,] int, void *, size_t)\*(C'\fR", see
570
\&\f(CW\*(C`SA_SYSCALL_WRITE\*(C'\fR: "\f(CW\*(C`ssize_t (*)([void *,] int, const void *,
571
size_t)\*(C'\fR", see \fIwrite\fR\|(2).
573
\&\f(CW\*(C`SA_SYSCALL_RECVFROM\*(C'\fR: "\f(CW\*(C`ssize_t (*)([void *,] int, void *, size_t,
574
int, struct sockaddr *, socklen_t *)\*(C'\fR", see \fIrecvfrom\fR\|(2).
576
\&\f(CW\*(C`SA_SYSCALL_SENDTO\*(C'\fR: "\f(CW\*(C`ssize_t (*)([void *,] int, const void *,
577
size_t, int, const struct sockaddr *, socklen_t)\*(C'\fR", see \fIsendto\fR\|(2).
582
\& FILE *trace_fp = ...;
587
\& trace_read(void *ctx, int fd, void *buf, size_t len)
589
\& FILE *fp = (FILE *)ctx;
595
\& rv = read(fd, buf, len);
596
\& errno_saved = errno;
597
\& fprintf(fp, "read(%d, %lx, %d) = %d\en",
598
\& fd, (long)buf, len, rv);
599
\& errno = errno_saved;
605
\& sa_syscall(sa, SA_SC_READ, trace_read, trace_fp);
607
.Sh "Socket Connection Operations"
608
.IX Subsection "Socket Connection Operations"
609
This \s-1API\s0 part provides connection operations for stream-oriented data
610
communication through the socket abstraction \f(CW\*(C`sa_t\*(C'\fR.
611
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_bind\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t *\*(C'\fR\fIladdr\fR\f(CW\*(C`);\*(C'" 4
612
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_bind\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t *\*(C'\fR\fIladdr\fR\f(CW\*(C`);\*(C'\fR" 4
613
.IX Item "sa_rc_t sa_bind(sa_t *sa, sa_addr_t *laddr);"
614
Bind socket abstraction object to a local protocol address.
616
This assigns the local protocol address \fIladdr\fR. When a socket is
617
created, it exists in an address family space but has no protocol
618
address assigned. This call requests that \fIladdr\fR be used as the local
619
address. For servers this is the address they later listen on (see
620
\&\fIsa_listen\fR\|(3)) for incoming connections, for clients this is the address
621
used for outgoing connections (see \fIsa_connect\fR\|(3)). Internally this
622
directly maps to \fIbind\fR\|(2).
624
Example: \f(CW\*(C`sa_bind(sa, laddr);\*(C'\fR
625
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_connect\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t *\*(C'\fR\fIraddr\fR\f(CW\*(C`);\*(C'" 4
626
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_connect\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t *\*(C'\fR\fIraddr\fR\f(CW\*(C`);\*(C'\fR" 4
627
.IX Item "sa_rc_t sa_connect(sa_t *sa, sa_addr_t *raddr);"
628
Initiate an outgoing connection on a socket abstraction object.
630
This performs a connect to the remote address \fIraddr\fR. If the socket
631
is of type \f(CW\*(C`SA_TYPE_DATAGRAM\*(C'\fR, this call specifies the peer with which
632
the socket is to be associated; this address is that to which datagrams
633
are to be sent, and the only address from which datagrams are to be
634
received. If the socket is of type \f(CW\*(C`SA_TYPE_STREAM\*(C'\fR, this call attempts
635
to make a connection to the remote socket. Internally this directly maps
636
to \fIconnect\fR\|(2).
638
Example: \f(CW\*(C`sa_connect(sa, raddr);\*(C'\fR
639
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_listen\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, int \*(C'\fR\fIbacklog\fR\f(CW\*(C`);\*(C'" 4
640
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_listen\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, int \*(C'\fR\fIbacklog\fR\f(CW\*(C`);\*(C'\fR" 4
641
.IX Item "sa_rc_t sa_listen(sa_t *sa, int backlog);"
642
Listen for incoming connections on a socket abstraction object.
644
A willingness to accept incoming connections and a queue limit for
645
incoming connections are specified by this call. The \fIbacklog\fR argument
646
defines the maximum length the queue of pending connections may grow to.
647
Internally this directly maps to \fIlisten\fR\|(2).
649
Example: \f(CW\*(C`sa_listen(sa, 128);\*(C'\fR
650
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_accept\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t **\*(C'\fR\fIcaddr\fR\f(CW\*(C`, sa_t **\*(C'\fR\fIcsa\fR\f(CW\*(C`);\*(C'" 4
651
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_accept\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t **\*(C'\fR\fIcaddr\fR\f(CW\*(C`, sa_t **\*(C'\fR\fIcsa\fR\f(CW\*(C`);\*(C'\fR" 4
652
.IX Item "sa_rc_t sa_accept(sa_t *sa, sa_addr_t **caddr, sa_t **csa);"
653
Accept incoming connection on a socket abstraction object.
655
This accepts an incoming connection by extracting the first connection
656
request on the queue of pending connections. It creates a new socket
657
abstraction object (returned in \fIcsa\fR) and a new socket address
658
abstraction object (returned in \fIcaddr\fR) describing the connection. The
659
caller has to destroy these objects later. If no pending connections
660
are present on the queue, it blocks the caller until a connection is
666
\& sa_addr_t *clt_saa;
669
\& while (sa_accept(srv_sa, &clt_saa, &clt_sa) == SA_OK) {
673
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_getremote\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t **\*(C'\fR\fIraddr\fR\f(CW\*(C`);\*(C'" 4
674
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_getremote\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t **\*(C'\fR\fIraddr\fR\f(CW\*(C`);\*(C'\fR" 4
675
.IX Item "sa_rc_t sa_getremote(sa_t *sa, sa_addr_t **raddr);"
676
Get address abstraction of remote side of communication.
678
This determines the address of the communication peer and creates a new
679
socket address abstraction object (returned in \fIraddr\fR) describing
680
the peer address. The application has to destroy \fIraddr\fR later with
681
\&\fIsa_addr_destroy\fR\|(3). Internally this maps to \fIgetpeername\fR\|(2).
683
Example: \f(CW\*(C`sa_addr_t *raddr; sa_getremote(sa, &raddr);\*(C'\fR
684
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_getlocal\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t **\*(C'\fR\fIladdr\fR\f(CW\*(C`);\*(C'" 4
685
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_getlocal\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t **\*(C'\fR\fIladdr\fR\f(CW\*(C`);\*(C'\fR" 4
686
.IX Item "sa_rc_t sa_getlocal(sa_t *sa, sa_addr_t **laddr);"
687
Get address abstraction of local side of communication.
689
This determines the address of the local communication side and
690
creates a new socket address abstraction object (returned in \fIladdr\fR)
691
describing the local address. The application has to destroy \fIladdr\fR
692
later with \fIsa_addr_destroy\fR\|(3). Internally this maps to \fIgetsockname\fR\|(2).
694
Example: \f(CW\*(C`sa_addr_t *laddr; sa_getlocal(sa, &laddr);\*(C'\fR
695
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_shutdown\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, char *\*(C'\fR\fIflags\fR\f(CW\*(C`);\*(C'" 4
696
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_shutdown\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, char *\*(C'\fR\fIflags\fR\f(CW\*(C`);\*(C'\fR" 4
697
.IX Item "sa_rc_t sa_shutdown(sa_t *sa, char *flags);"
698
Shut down part of the full-duplex connection.
700
This performs a shut down of the connection described in \fIsa\fR. The
701
flags string can be either "\f(CW\*(C`r\*(C'\fR\*(L" (indicating the read channel of the
702
communication is shut down only), \*(R"\f(CW\*(C`w\*(C'\fR\*(L" (indicating the write channel
703
of the communication is shut down only), or \*(R"\f(CW\*(C`rw\*(C'\fR" (indicating both the
704
read and write channels of the communication are shut down). Internally
705
this directly maps to \fIshutdown\fR\|(2).
707
Example: \f(CW\*(C`sa_shutdown(sa, "w");\*(C'\fR
708
.Sh "Socket Input/Output Operations (Stream Communication)"
709
.IX Subsection "Socket Input/Output Operations (Stream Communication)"
710
This \s-1API\s0 part provides I/O operations for stream-oriented data
711
communication through the socket abstraction \f(CW\*(C`sa_t\*(C'\fR.
712
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_getfd\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, int *\*(C'\fR\fIfd\fR\f(CW\*(C`);\*(C'" 4
713
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_getfd\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, int *\*(C'\fR\fIfd\fR\f(CW\*(C`);\*(C'\fR" 4
714
.IX Item "sa_rc_t sa_getfd(sa_t *sa, int *fd);"
715
Get underlying socket filedescriptor.
717
This peeks into the underlying socket filedescriptor \fB\s-1OSSP\s0 sa\fR
718
allocated internally for the communication. This can be used for
719
adjusting the socket communication (via \fIfcntl\fR\|(2), \fIsetsockopt\fR\|(2), etc)
722
Think twice before using this, then think once more. After all that,
723
think again. With enough thought, the need for directly manipulating the
724
underlying socket can often be eliminated. At least remember that all
725
your direct socket operations fully by-pass \fB\s-1OSSP\s0 sa\fR and this way can
726
leads to nasty side\-effects.
728
Example: \f(CW\*(C`int fd; sa_getfd(sa, &fd);\*(C'\fR
729
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_read\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, char *\*(C'\fR\fIbuf\fR\f(CW\*(C`, size_t \*(C'\fR\fIbuflen\fR\f(CW\*(C`, size_t *\*(C'\fR\fIbufdone\fR\f(CW\*(C`);\*(C'" 4
730
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_read\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, char *\*(C'\fR\fIbuf\fR\f(CW\*(C`, size_t \*(C'\fR\fIbuflen\fR\f(CW\*(C`, size_t *\*(C'\fR\fIbufdone\fR\f(CW\*(C`);\*(C'\fR" 4
731
.IX Item "sa_rc_t sa_read(sa_t *sa, char *buf, size_t buflen, size_t *bufdone);"
732
Read a chunk of data from socket into own buffer.
734
This reads from the socket (optionally through the internal read buffer)
735
up to a maximum of \fIbuflen\fR bytes into buffer \fIbuf\fR. The actual number
736
of read bytes is stored in \fIbufdone\fR. This internally maps to \fIread\fR\|(2).
738
Example: \f(CW\*(C`char buf[1024]; size_t n; sa_read(sa, buf, sizeof(buf), &n);\*(C'\fR
739
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_readln\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, char *\*(C'\fR\fIbuf\fR\f(CW\*(C`, size_t \*(C'\fR\fIbuflen\fR\f(CW\*(C`, size_t *\*(C'\fR\fIbufdone\fR\f(CW\*(C`);\*(C'" 4
740
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_readln\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, char *\*(C'\fR\fIbuf\fR\f(CW\*(C`, size_t \*(C'\fR\fIbuflen\fR\f(CW\*(C`, size_t *\*(C'\fR\fIbufdone\fR\f(CW\*(C`);\*(C'\fR" 4
741
.IX Item "sa_rc_t sa_readln(sa_t *sa, char *buf, size_t buflen, size_t *bufdone);"
742
Read a line of data from socket into own buffer.
744
This reads from the socket (optionally through the internal read buffer)
745
up to a maximum of \fIbuflen\fR bytes into buffer \fIbuf\fR, but only as long
746
as no line terminating newline character (0x0a) was found. The line
747
terminating newline character is stored in the buffer plus a (not
748
counted) terminating \f(CW\*(C`NUL\*(C'\fR character ('\f(CW\*(C`\e0\*(C'\fR'), too. The actual
749
number of read bytes is stored in \fIbufdone\fR. This internally maps to
750
\&\fIsa_read\fR\|(3).
752
Keep in mind that for efficiency reasons, line-oriented I/O usually
753
always should be performed with read buffer (see \fIsa_option\fR\|(3) and
754
\&\f(CW\*(C`SA_BUFFER_READ\*(C'\fR). Without such a read buffer, the performance is
755
cruel, because single character \fIread\fR\|(2) operations would be performed on
756
the underlying socket.
758
Example: \f(CW\*(C`char buf[1024]; size_t n; sa_readln(sa, buf, sizeof(buf), &n);\*(C'\fR
759
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_write\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, const char *\*(C'\fR\fIbuf\fR\f(CW\*(C`, size_t \*(C'\fR\fIbuflen\fR\f(CW\*(C`, size_t *\*(C'\fR\fIbufdone\fR\f(CW\*(C`);\*(C'" 4
760
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_write\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, const char *\*(C'\fR\fIbuf\fR\f(CW\*(C`, size_t \*(C'\fR\fIbuflen\fR\f(CW\*(C`, size_t *\*(C'\fR\fIbufdone\fR\f(CW\*(C`);\*(C'\fR" 4
761
.IX Item "sa_rc_t sa_write(sa_t *sa, const char *buf, size_t buflen, size_t *bufdone);"
762
Write a chunk of data to socket from own buffer.
764
This writes to the socket (optionally through the internal write buffer)
765
\&\fIbuflen\fR bytes from buffer \fIbuf\fR. In case of a partial write, the
766
actual number of written bytes is stored in \fIbufdone\fR. This internally
767
maps to \fIwrite\fR\|(2).
769
Example: \f(CW\*(C`sa_write(sa, cp, strlen(cp), NULL);\*(C'\fR
770
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_writef\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, const char *\*(C'\fR\fIfmt\fR\f(CW\*(C`, ...);\*(C'" 4
771
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_writef\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, const char *\*(C'\fR\fIfmt\fR\f(CW\*(C`, ...);\*(C'\fR" 4
772
.IX Item "sa_rc_t sa_writef(sa_t *sa, const char *fmt, ...);"
773
Write formatted data data to socket.
775
This formats a string according to the \fIprintf\fR\|(3)\-style format
776
specification \fIfmt\fR and sends the result to the socket (optionally
777
through the internal write buffer). In case of a partial socket
778
write, the not written data of the formatted string is internally
779
discarded. Hence using a write buffer is strongly recommended here
780
(see \fIsa_option\fR\|(3) and \f(CW\*(C`SA_BUFFER_WRITE\*(C'\fR). This internally maps to
781
\&\fIsa_write\fR\|(3).
783
The underlying string formatting engine is just a minimal one and for
784
security and independence reasons intentionally not directly based on
785
s[n]\fIprintf\fR\|(3). It understands only the following format specifications:
786
"\f(CW\*(C`%%\*(C'\fR\*(L", \*(R"\f(CW%c\fR" (\f(CW\*(C`char\*(C'\fR), "\f(CW%s\fR" (\f(CW\*(C`char *\*(C'\fR) and "\f(CW%d\fR" (\f(CW\*(C`int\*(C'\fR)
787
without any precision and padding possibilities. It is intended for
788
minimal formatting only. If you need more sophisticated formatting, you
789
have to format first into an own buffer via s[n]\fIprintf\fR\|(3) and then write
790
this to the socket via \fIsa_write\fR\|(3) instead.
792
Example: \f(CW\*(C`sa_writef(sa, "%s=%d\en", cp, i);\*(C'\fR
793
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_flush\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`);\*(C'" 4
794
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_flush\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`);\*(C'\fR" 4
795
.IX Item "sa_rc_t sa_flush(sa_t *sa);"
796
Flush still pending outgoing data to socket.
798
This writes all still pending outgoing data for the internal write
799
buffer (see \fIsa_option\fR\|(3) and \f(CW\*(C`SA_BUFFER_WRITE\*(C'\fR) to the socket. This
800
internally maps to \fIwrite\fR\|(2).
802
Example: \f(CW\*(C`sa_flush(sa);\*(C'\fR
803
.Sh "Socket Input/Output Operations (Datagram Communication)"
804
.IX Subsection "Socket Input/Output Operations (Datagram Communication)"
805
This \s-1API\s0 part provides I/O operations for datagram-oriented data
806
communication through the socket abstraction \f(CW\*(C`sa_t\*(C'\fR.
807
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_recv\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t **\*(C'\fR\fIraddr\fR\f(CW\*(C`, char *\*(C'\fR\fIbuf\fR\f(CW\*(C`, size_t \*(C'\fR\fIbuflen\fR\f(CW\*(C`, size_t *\*(C'\fR\fIbufdone\fR\f(CW\*(C`);\*(C'" 4
808
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_recv\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t **\*(C'\fR\fIraddr\fR\f(CW\*(C`, char *\*(C'\fR\fIbuf\fR\f(CW\*(C`, size_t \*(C'\fR\fIbuflen\fR\f(CW\*(C`, size_t *\*(C'\fR\fIbufdone\fR\f(CW\*(C`);\*(C'\fR" 4
809
.IX Item "sa_rc_t sa_recv(sa_t *sa, sa_addr_t **raddr, char *buf, size_t buflen, size_t *bufdone);"
810
Receive a chunk of data from remote address via socket into own buffer.
812
This receives from the remote address specified in \fIraddr\fR via the
813
socket up to a maximum of \fIbuflen\fR bytes into buffer \fIbuf\fR. The actual
814
number of received bytes is stored in \fIbufdone\fR. This internally maps
815
to \fIrecvfrom\fR\|(2).
817
Example: \f(CW\*(C`char buf[1024]; size_t n; sa_recv(sa, buf, sizeof(buf), &n, saa);\*(C'\fR
818
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_send\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t *\*(C'\fR\fIraddr\fR\f(CW\*(C`, const char *\*(C'\fR\fIbuf\fR\f(CW\*(C`, size_t \*(C'\fR\fIbuflen\fR\f(CW\*(C`, size_t *\*(C'\fR\fIbufdone\fR\f(CW\*(C`);\*(C'" 4
819
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_send\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t *\*(C'\fR\fIraddr\fR\f(CW\*(C`, const char *\*(C'\fR\fIbuf\fR\f(CW\*(C`, size_t \*(C'\fR\fIbuflen\fR\f(CW\*(C`, size_t *\*(C'\fR\fIbufdone\fR\f(CW\*(C`);\*(C'\fR" 4
820
.IX Item "sa_rc_t sa_send(sa_t *sa, sa_addr_t *raddr, const char *buf, size_t buflen, size_t *bufdone);"
821
Send a chunk of data to remote address via socket from own buffer.
823
This sends to the remote address specified in \fIraddr\fR via the socket
824
\&\fIbuflen\fR bytes from buffer \fIbuf\fR. The actual number of sent bytes is
825
stored in \fIbufdone\fR. This internally maps to \fIsendto\fR\|(2).
827
Example: \f(CW\*(C`sa_send(sa, buf, strlen(buf), NULL, saa);\*(C'\fR
828
.ie n .IP "\*(C`sa_rc_t \*(C'\fR\fBsa_sendf\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t *\*(C'\fR\fIraddr\fR\f(CW\*(C`, const char *\*(C'\fR\fIfmt\fR\f(CW\*(C`, ...);\*(C'" 4
829
.el .IP "\f(CW\*(C`sa_rc_t \*(C'\fR\fBsa_sendf\fR\f(CW\*(C`(sa_t *\*(C'\fR\fIsa\fR\f(CW\*(C`, sa_addr_t *\*(C'\fR\fIraddr\fR\f(CW\*(C`, const char *\*(C'\fR\fIfmt\fR\f(CW\*(C`, ...);\*(C'\fR" 4
830
.IX Item "sa_rc_t sa_sendf(sa_t *sa, sa_addr_t *raddr, const char *fmt, ...);"
831
Send formatted data data to remote address via socket.
833
This formats a string according to the \fIprintf\fR\|(3)\-style format
834
specification \fIfmt\fR and sends the result to the socket as a single
835
piece of data chunk. In case of a partial socket write, the not written
836
data of the formatted string is internally discarded.
838
The underlying string formatting engine is just a minimal one and for
839
security and independence reasons intentionally not directly based on
840
s[n]\fIprintf\fR\|(3). It understands only the following format specifications:
841
"\f(CW\*(C`%%\*(C'\fR\*(L", \*(R"\f(CW%c\fR" (\f(CW\*(C`char\*(C'\fR), "\f(CW%s\fR" (\f(CW\*(C`char *\*(C'\fR) and "\f(CW%d\fR" (\f(CW\*(C`int\*(C'\fR)
842
without any precision and padding possibilities. It is intended for
843
minimal formatting only. If you need more sophisticated formatting, you
844
have to format first into an own buffer via s[n]\fIprintf\fR\|(3) and then send
845
this to the remote address via \fIsa_send\fR\|(3) instead.
847
Example: \f(CW\*(C`sa_sendf(sa, saa, "%s=%d\en", cp, i);\*(C'\fR
848
.Sh "Socket Error Handling"
849
.IX Subsection "Socket Error Handling"
850
This \s-1API\s0 part provides error handling operations only.
851
.ie n .IP "\*(C`char *\*(C'\fR\fBsa_error\fR\f(CW\*(C`(sa_rc_t \*(C'\fR\fIrv\fR\f(CW\*(C`);\*(C'" 4
852
.el .IP "\f(CW\*(C`char *\*(C'\fR\fBsa_error\fR\f(CW\*(C`(sa_rc_t \*(C'\fR\fIrv\fR\f(CW\*(C`);\*(C'\fR" 4
853
.IX Item "char *sa_error(sa_rc_t rv);"
854
Return the string representation corresponding to the return code
855
value \fIrv\fR. The returned string has to be treated read-only by the
856
application and is not required to be deallocated.
858
.IX Header "SEE ALSO"
860
.IX Subsection "Standards"
861
R. Gilligan, S. Thomson, J. Bound, W. Stevens:
862
\&\fI\*(L"Basic Socket Interface Extensions for IPv6\*(R"\fR,
863
\&\fB\s-1RFC\s0 2553\fR, March 1999.
866
\&\fI\*(L"Advanced Sockets \s-1API\s0 for IPv6\*(R"\fR,
867
\&\fB\s-1RFC\s0 2292\fR, February 1998.
869
R. Fielding, L. Masinter, T. Berners\-Lee:
870
\&\fI\*(L"Uniform Resource Identifiers: Generic Syntax\*(R"\fR,
871
\&\fB\s-1RFC\s0 2396\fR, August 1998.
873
R. Hinden, S. Deering:
874
\&\fI\*(L"\s-1IP\s0 Version 6 Addressing Architecture\*(R"\fR,
875
\&\fB\s-1RFC\s0 2373\fR, July 1998.
877
R. Hinden, B. Carpenter, L. Masinter:
878
\&\fI\*(L"Format for Literal IPv6 Addresses in \s-1URL\s0's\*(R"\fR,
879
\&\fB\s-1RFC\s0 2732\fR, December 1999.
881
.IX Subsection "Papers"
883
\&\fI\*(L"An Introductory 4.4BSD Interprocess Communication Tutorial\*(R"\fR,
884
FreeBSD 4.4 (/usr/share/doc/psd/20.ipctut/).
886
Samuel J. Leffler, Robert S. Fabry, William N. Joy, Phil Lapsley:
887
\&\fI\*(L"An Advanced 4.4BSD Interprocess Communication Tutorial\*(R"\fR,
888
FreeBSD 4.4 (/usr/share/doc/psd/21.ipc/).
891
\&\fI\*(L"Protocol Independence Using the Sockets \s-1API\s0\*(R"\fR,
892
http://www.usenix.org/publications/library/proceedings/usenix2000/freenix/metzprotocol.html,
893
\&\s-1USENIX\s0 Annual Technical Conference, June 2000.
895
.IX Subsection "Manual Pages"
899
\&\fIconnect\fR\|(2),
900
\&\fIgetpeername\fR\|(2),
901
\&\fIgetsockname\fR\|(2),
902
\&\fIgetsockopt\fR\|(2),
909
\&\fIshutdown\fR\|(2),
910
\&\fIsocketpair\fR\|(2),
912
\&\fIgetprotoent\fR\|(3),
913
\&\fIprotocols\fR\|(4).
916
\&\fB\s-1OSSP\s0 sa\fR was invented in August 2001 by Ralf S. Engelschall
917
<rse@engelschall.com> under contract with Cable & Wireless
918
Germany <http://www.cw.com/de> for use inside the \s-1OSSP\s0 project.
919
Its creation was prompted by the requirement to implement an \s-1SMTP\s0
920
logging channel for \fB\s-1OSSP\s0 l2\fR (logging library). Its initial code was
921
derived from a predecessor sub-library originally written for socket
922
address abstraction inside \fB\s-1OSSP\s0 lmtp2nntp\fR.
926
\& Ralf S. Engelschall
927
\& rse@engelschall.com
928
\& www.engelschall.com