Commit | Line | Data |
---|---|---|
1e7e4330 | 1 | .\" -*-nroff-*- |
c4ccbbf9 MW |
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" | |
1e7e4330 | 32 | .\" @pkbuf_flush |
33 | .\" @pkbuf_close | |
34 | .\" @pkbuf_free | |
35 | .\" @pkbuf_snarf | |
36 | .\" @pkbuf_want | |
37 | .\" @pkbuf_init | |
38 | .\" @pkbuf_destroy | |
c4ccbbf9 MW |
39 | . |
40 | .\"-------------------------------------------------------------------------- | |
41 | .SH "NAME" | |
42 | pkbuf \- split packets out of asynchronously received blocks | |
43 | . | |
44 | .\"-------------------------------------------------------------------------- | |
1e7e4330 | 45 | .SH "SYNOPSIS" |
c4ccbbf9 | 46 | . |
1e7e4330 | 47 | .nf |
adec5584 | 48 | .ta 2n |
1e7e4330 | 49 | .B "#include <mLib/pkbuf.h>" |
d056fbdf | 50 | .PP |
4729aa69 | 51 | .B "enum {" |
adec5584 | 52 | .B " PKBUF_ENABLE = ..." |
4729aa69 | 53 | .B "};" |
d056fbdf | 54 | .PP |
4729aa69 | 55 | .B "typedef struct {" |
adec5584 MW |
56 | .B " unsigned f;" |
57 | .B " ..." | |
4729aa69 | 58 | .B "} pkbuf;" |
d056fbdf | 59 | .PP |
adec5584 MW |
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 ); | |
d056fbdf | 63 | .PP |
1e7e4330 | 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 ); | |
0daaeb18 | 69 | .BI "void pkbuf_init(pkbuf *" pk ", pkbuf_func *" func ", void *" p ); |
1e7e4330 | 70 | .BI "void pkbuf_destroy(pkbuf *" pk ); |
71 | .fi | |
c4ccbbf9 MW |
72 | . |
73 | .\"-------------------------------------------------------------------------- | |
74 | SH "DESCRIPTION" | |
75 | . | |
1e7e4330 | 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 | |
d4efbcd9 | 82 | function. |
1e7e4330 | 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). | |
c4ccbbf9 | 90 | . |
1e7e4330 | 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 | |
0daaeb18 | 101 | .BI "pkbuf_func *" func |
1e7e4330 | 102 | The |
103 | .I packet-handler | |
104 | function to which the packet buffer should pass packets of data when | |
0daaeb18 | 105 | they're received. See |
106 | .B "Packet breaking and the handler function" | |
107 | below. | |
1e7e4330 | 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. | |
c4ccbbf9 | 123 | . |
1e7e4330 | 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 | |
528c8b4d | 134 | to a chunk of data to read; and the size |
1e7e4330 | 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 | |
d4efbcd9 | 144 | The |
1e7e4330 | 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 | |
d4efbcd9 | 148 | the address |
1e7e4330 | 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 | |
528c8b4d | 184 | .BR pkbuf_free / pkbuf_flush |
1e7e4330 | 185 | interface. |
c4ccbbf9 | 186 | . |
0daaeb18 | 187 | .SS "Packet breaking and the handler function" |
1e7e4330 | 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 | |
4729aa69 MW |
197 | When enough data has arrived, the packet-handler function is called. It |
198 | is passed: | |
1e7e4330 | 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 | |
c4ccbbf9 | 221 | . |
1e7e4330 | 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. | |
c4ccbbf9 | 229 | . |
1e7e4330 | 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 | |
528c8b4d | 243 | call can emit more than one packet, it must be aware that the packet |
1e7e4330 | 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 | |
3bc42912 | 249 | exports one of its structure members, a flags words called |
250 | .BR f . | |
1e7e4330 | 251 | A higher-level object wishing to disable the packet buffer simply clears |
252 | the bit | |
253 | .B PKBUF_ENABLE | |
3bc42912 | 254 | in this flags word. |
1e7e4330 | 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 . | |
c4ccbbf9 MW |
269 | . |
270 | .\"-------------------------------------------------------------------------- | |
1e7e4330 | 271 | .SH "SEE ALSO" |
c4ccbbf9 | 272 | . |
1e7e4330 | 273 | .BR lbuf (3), |
274 | .BR selpk (3), | |
275 | .BR mLib (3). | |
c4ccbbf9 MW |
276 | . |
277 | .\"-------------------------------------------------------------------------- | |
1e7e4330 | 278 | .SH "AUTHOR" |
c4ccbbf9 | 279 | . |
9b5ac6ff | 280 | Mark Wooding, <mdw@distorted.org.uk> |
c4ccbbf9 MW |
281 | . |
282 | .\"----- That's all, folks -------------------------------------------------- |