chiark / gitweb /
@@@ fltfmt wip
[mLib] / buf / pkbuf.3.in
1 .\" -*-nroff-*-
2 .\"
3 .\" Manual for packet splitting
4 .\"
5 .\" (c) 1999--2003, 2005, 2007, 2009, 2023, 2024 Straylight/Edgeware
6 .\"
7 .
8 .\"----- Licensing notice ---------------------------------------------------
9 .\"
10 .\" This file is part of the mLib utilities library.
11 .\"
12 .\" mLib is free software: you can redistribute it and/or modify it under
13 .\" the terms of the GNU Library General Public License as published by
14 .\" the Free Software Foundation; either version 2 of the License, or (at
15 .\" your option) any later version.
16 .\"
17 .\" mLib is distributed in the hope that it will be useful, but WITHOUT
18 .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 .\" FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
20 .\" License for more details.
21 .\"
22 .\" You should have received a copy of the GNU Library General Public
23 .\" License along with mLib.  If not, write to the Free Software
24 .\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
25 .\" USA.
26 .
27 .\"--------------------------------------------------------------------------
28 .so ../defs.man \" @@@PRE@@@
29 .
30 .\"--------------------------------------------------------------------------
31 .TH pkbuf 3mLib "16 July 2000" "Straylight/Edgeware" "mLib utilities library"
32 .\" @pkbuf_flush
33 .\" @pkbuf_close
34 .\" @pkbuf_free
35 .\" @pkbuf_snarf
36 .\" @pkbuf_want
37 .\" @pkbuf_init
38 .\" @pkbuf_destroy
39 .
40 .\"--------------------------------------------------------------------------
41 .SH "NAME"
42 pkbuf \- split packets out of asynchronously received blocks
43 .
44 .\"--------------------------------------------------------------------------
45 .SH "SYNOPSIS"
46 .
47 .nf
48 .ta 2n
49 .B "#include <mLib/pkbuf.h>"
50 .PP
51 .B "enum {"
52 .B "    PKBUF_ENABLE = ..."
53 .B "};"
54 .PP
55 .B "typedef struct {"
56 .B "    unsigned f;"
57 .B "    ..."
58 .B "} pkbuf;"
59 .PP
60 .ta \w'\fBtypedef void pkbuf_func('u
61 .B "typedef void pkbuf_func(octet *" b ", size_t " sz ", pkbuf *" p ,
62 .BI "   size_t *" keep ", void *" p );
63 .PP
64 .BI "void pkbuf_flush(pkbuf *" pk ", octet *" p ", size_t " len );
65 .BI "void pkbuf_close(pkbuf *" pk );
66 .BI "size_t pkbuf_free(pkbuf *" pk ", octet **" p );
67 .BI "void pkbuf_snarf(pkbuf *" pk ", const void *" p ", size_t " sz );
68 .BI "void pkbuf_want(pkbuf *" pk ", size_t " want );
69 .BI "void pkbuf_init(pkbuf *" pk ", pkbuf_func *" func ", void *" p );
70 .BI "void pkbuf_destroy(pkbuf *" pk );
71 .fi
72 .
73 .\"--------------------------------------------------------------------------
74 SH "DESCRIPTION"
75 .
76 The declarations in
77 .B <mLib/pkbuf.h>
78 implement a
79 .IR "packet buffer" .
80 Given unpredictably-sized chunks of data, the packet buffer extracts
81 completed packets of data, with sizes ascertained by a handler
82 function.
83 .PP
84 The state of a packet buffer is stored in an object of type
85 .BR pkbuf .
86 This is a structure which must be allocated by the caller.  The
87 structure should normally be considered opaque (see the section on
88 .B Disablement
89 for an exception to this).
90 .
91 .SS "Initialization and finalization"
92 The function
93 .B pkbuf_init
94 initializes a packet buffer ready for use.  It is given three arguments:
95 .TP
96 .BI "pkbuf *" pk
97 A pointer to the block of memory to use for the packet buffer.  The packet
98 buffer will allocate memory to store incoming data automatically: this
99 structure just contains bookkeeping information.
100 .TP
101 .BI "pkbuf_func *" func
102 The
103 .I packet-handler
104 function to which the packet buffer should pass packets of data when
105 they're received.  See
106 .B "Packet breaking and the handler function"
107 below.
108 .TP
109 .BI "void *" p
110 A pointer argument to be passed to the function when a packet arrives.
111 .PP
112 By default, the buffer is
113 allocated from the current arena,
114 .BR arena_global (3);
115 this may be changed by altering the buffer's
116 .B a
117 member to refer to a different arena at any time when the buffer is
118 unallocated.
119 .PP
120 A packet buffer must be destroyed after use by calling
121 .BR pkbuf_destroy ,
122 passing it the address of the buffer block.
123 .
124 .SS "Inserting data into the buffer"
125 There are two interfaces for inserting data into the buffer.  One's much
126 simpler than the other, although it's less expressive.
127 .PP
128 The simple interface is
129 .BR pkbuf_snarf .
130 This function is given three arguments: a pointer
131 .I pk
132 to a packet buffer structure; a pointer
133 .I p
134 to a chunk of data to read; and the size
135 .I sz
136 of the chunk of data.  The data is pushed through the packet buffer and
137 any complete packets are passed on to the packet handler.
138 .PP
139 The complex interface is the pair of functions
140 .I pkbuf_free
141 and
142 .IR pkbuf_flush .
143 .PP
144 The
145 .B pkbuf_free
146 function returns the address and size of a free portion of the packet
147 buffer's memory into which data may be written.  The function is passed
148 the address
149 .I pk
150 of the packet buffer.  Its result is the size of the free area, and it
151 writes the base address of this free space to the location pointed to by
152 the argument
153 .IR p .
154 The caller's data must be written to ascending memory locations starting
155 at
156 .BI * p
157 and no data may be written beyond the end of the free space.  However,
158 it isn't necessary to completely fill the buffer.
159 .PP
160 Once the free area has had some data written to it,
161 .B pkbuf_flush
162 is called to examine the new data and break it into packets.  This is
163 given three arguments:
164 .TP
165 .BI "pkbuf *" pk
166 The address of the packet buffer.
167 .TP
168 .BI "octet *" p
169 The address at which the new data has been written.  This must be the
170 base address returned from
171 .BR pkbuf_free .
172 .TP
173 .BI "size_t " len
174 The number of bytes which have been written to the buffer.
175 .PP
176 The
177 .B pkbuf_flush
178 function breaks the new data into packets as described below, and passes
179 each one in turn to the packet-handler function.
180 .PP
181 The
182 .B pkbuf_snarf
183 function is trivially implemented in terms of the more complex
184 .BR pkbuf_free / pkbuf_flush
185 interface.
186 .
187 .SS "Packet breaking and the handler function"
188 The function
189 .B pkbuf_want
190 is used to inform the packet buffer of the expected length of the next
191 packet.  It is given the pointer
192 .I pk
193 to the packet buffer and a size
194 .I sz
195 of the packet.
196 .PP
197 When enough data has arrived, the packet-handler function is called.  It
198 is passed:
199 .TP
200 .BI "octet *" b
201 A pointer to the packet data in the buffer, or zero to signify
202 end-of-file.
203 .TP
204 .BI "size_t " sz
205 The size of the packet, as previously configured via
206 .BR pkbuf_want .
207 .TP
208 .BI "pkbuf *" pk
209 A pointer to the packet buffer.
210 .TP
211 .BI "size_t *" keep
212 A location in which to store the number of bytes of the current packet
213 to be retained.  The bytes kept are from the end of the current packet:
214 if you want to keep bytes from the beginning of the packet, you should
215 move them into the right place.
216 .TP
217 .BI "void *" p
218 The pointer which was set up in the call to
219 .BR pkbuf_init .
220 .PP
221 .
222 .SS "Flushing the remaining data"
223 When the client program knows that there's no more data arriving (for
224 example, an end-of-file condition exists on its data source) it should
225 call the function
226 .BR pkbuf_close .
227 This will call the handler one final time with a null pointer to inform
228 it of the end-of-file.
229 .
230 .SS "Disablement"
231 The packet buffer is intended to be used in higher-level program
232 objects, such as the packet selector described in
233 .BR selpk (3).
234 Unfortunately, a concept from this high level needs to exist at the
235 packet buffer level, which complicates the description somewhat.  The
236 idea is that, when a packet-handler attached to some higher-level object
237 decides that it's read enough, it can
238 .I disable
239 the object so that it doesn't see any more data.
240 .PP
241 Clearly, since an
242 .B pkbuf_flush
243 call can emit more than one packet, it must be aware that the packet
244 handler isn't interested in any more packet.  However, this fact must
245 also be signalled to the higher-level object so that it can detach
246 itself from its data source.
247 .PP
248 Rather than invent some complex interface for this, the packet buffer
249 exports one of its structure members, a flags words called
250 .BR f .
251 A higher-level object wishing to disable the packet buffer simply clears
252 the bit
253 .B PKBUF_ENABLE
254 in this flags word.
255 .PP
256 Disabling a buffer causes an immediate return from
257 .BR pkbuf_flush .
258 However, it is not permitted for the functions
259 .B pkbuf_flush
260 or
261 .B pkbuf_close
262 to be called on a disabled buffer.  (This condition isn't checked for;
263 it'll just do the wrong thing.)  Furthermore, the
264 .B pkbuf_snarf
265 function does not handle disablement at all, because it would complicate
266 the interface so much that it wouldn't have any advantage over the more
267 general
268 .BR pkbuf_free / pkbuf_flush .
269 .
270 .\"--------------------------------------------------------------------------
271 .SH "SEE ALSO"
272 .
273 .BR lbuf (3),
274 .BR selpk (3),
275 .BR mLib (3).
276 .
277 .\"--------------------------------------------------------------------------
278 .SH "AUTHOR"
279 .
280 Mark Wooding, <mdw@distorted.org.uk>
281 .
282 .\"----- That's all, folks --------------------------------------------------