1e7e4330 |
1 | .\" -*-nroff-*- |
fbf20b5b |
2 | .TH pkbuf 3 "16 July 2000" "Straylight/Edgeware" "mLib utilities library" |
1e7e4330 |
3 | .SH "NAME" |
4 | pkbuf \- split packets out of asynchronously received blocks |
5 | .\" @pkbuf_flush |
6 | .\" @pkbuf_close |
7 | .\" @pkbuf_free |
8 | .\" @pkbuf_snarf |
9 | .\" @pkbuf_want |
10 | .\" @pkbuf_init |
11 | .\" @pkbuf_destroy |
12 | .SH "SYNOPSIS" |
13 | .nf |
14 | .B "#include <mLib/pkbuf.h>" |
15 | |
16 | .BI "void pkbuf_flush(pkbuf *" pk ", octet *" p ", size_t " len ); |
17 | .BI "void pkbuf_close(pkbuf *" pk ); |
18 | .BI "size_t pkbuf_free(pkbuf *" pk ", octet **" p ); |
19 | .BI "void pkbuf_snarf(pkbuf *" pk ", const void *" p ", size_t " sz ); |
20 | .BI "void pkbuf_want(pkbuf *" pk ", size_t " want ); |
0daaeb18 |
21 | .BI "void pkbuf_init(pkbuf *" pk ", pkbuf_func *" func ", void *" p ); |
1e7e4330 |
22 | .BI "void pkbuf_destroy(pkbuf *" pk ); |
23 | .fi |
24 | .SH "DESCRIPTION" |
25 | The declarations in |
26 | .B <mLib/pkbuf.h> |
27 | implement a |
28 | .IR "packet buffer" . |
29 | Given unpredictably-sized chunks of data, the packet buffer extracts |
30 | completed packets of data, with sizes ascertained by a handler |
d4efbcd9 |
31 | function. |
1e7e4330 |
32 | .PP |
33 | The state of a packet buffer is stored in an object of type |
34 | .BR pkbuf . |
35 | This is a structure which must be allocated by the caller. The |
36 | structure should normally be considered opaque (see the section on |
37 | .B Disablement |
38 | for an exception to this). |
39 | .SS "Initialization and finalization" |
40 | The function |
41 | .B pkbuf_init |
42 | initializes a packet buffer ready for use. It is given three arguments: |
43 | .TP |
44 | .BI "pkbuf *" pk |
45 | A pointer to the block of memory to use for the packet buffer. The packet |
46 | buffer will allocate memory to store incoming data automatically: this |
47 | structure just contains bookkeeping information. |
48 | .TP |
0daaeb18 |
49 | .BI "pkbuf_func *" func |
1e7e4330 |
50 | The |
51 | .I packet-handler |
52 | function to which the packet buffer should pass packets of data when |
0daaeb18 |
53 | they're received. See |
54 | .B "Packet breaking and the handler function" |
55 | below. |
1e7e4330 |
56 | .TP |
57 | .BI "void *" p |
58 | A pointer argument to be passed to the function when a packet arrives. |
59 | .PP |
60 | By default, the buffer is |
61 | allocated from the current arena, |
62 | .BR arena_global (3); |
63 | this may be changed by altering the buffer's |
64 | .B a |
65 | member to refer to a different arena at any time when the buffer is |
66 | unallocated. |
67 | .PP |
68 | A packet buffer must be destroyed after use by calling |
69 | .BR pkbuf_destroy , |
70 | passing it the address of the buffer block. |
71 | .SS "Inserting data into the buffer" |
72 | There are two interfaces for inserting data into the buffer. One's much |
73 | simpler than the other, although it's less expressive. |
74 | .PP |
75 | The simple interface is |
76 | .BR pkbuf_snarf . |
77 | This function is given three arguments: a pointer |
78 | .I pk |
79 | to a packet buffer structure; a pointer |
80 | .I p |
528c8b4d |
81 | to a chunk of data to read; and the size |
1e7e4330 |
82 | .I sz |
83 | of the chunk of data. The data is pushed through the packet buffer and |
84 | any complete packets are passed on to the packet handler. |
85 | .PP |
86 | The complex interface is the pair of functions |
87 | .I pkbuf_free |
88 | and |
89 | .IR pkbuf_flush . |
90 | .PP |
d4efbcd9 |
91 | The |
1e7e4330 |
92 | .B pkbuf_free |
93 | function returns the address and size of a free portion of the packet |
94 | buffer's memory into which data may be written. The function is passed |
d4efbcd9 |
95 | the address |
1e7e4330 |
96 | .I pk |
97 | of the packet buffer. Its result is the size of the free area, and it |
98 | writes the base address of this free space to the location pointed to by |
99 | the argument |
100 | .IR p . |
101 | The caller's data must be written to ascending memory locations starting |
102 | at |
103 | .BI * p |
104 | and no data may be written beyond the end of the free space. However, |
105 | it isn't necessary to completely fill the buffer. |
106 | .PP |
107 | Once the free area has had some data written to it, |
108 | .B pkbuf_flush |
109 | is called to examine the new data and break it into packets. This is |
110 | given three arguments: |
111 | .TP |
112 | .BI "pkbuf *" pk |
113 | The address of the packet buffer. |
114 | .TP |
115 | .BI "octet *" p |
116 | The address at which the new data has been written. This must be the |
117 | base address returned from |
118 | .BR pkbuf_free . |
119 | .TP |
120 | .BI "size_t " len |
121 | The number of bytes which have been written to the buffer. |
122 | .PP |
123 | The |
124 | .B pkbuf_flush |
125 | function breaks the new data into packets as described below, and passes |
126 | each one in turn to the packet-handler function. |
127 | .PP |
128 | The |
129 | .B pkbuf_snarf |
130 | function is trivially implemented in terms of the more complex |
528c8b4d |
131 | .BR pkbuf_free / pkbuf_flush |
1e7e4330 |
132 | interface. |
0daaeb18 |
133 | .SS "Packet breaking and the handler function" |
1e7e4330 |
134 | The function |
135 | .B pkbuf_want |
136 | is used to inform the packet buffer of the expected length of the next |
137 | packet. It is given the pointer |
138 | .I pk |
139 | to the packet buffer and a size |
140 | .I sz |
141 | of the packet. |
142 | .PP |
0daaeb18 |
143 | When enough data has arrived, the packet-handler function is called. |
144 | This has the signature |
145 | .IP |
146 | .nf |
147 | .BI "void (*" func ")(octet *" b ", size_t " sz ", pkbuf *" p , |
148 | .BI " size_t *" keep ", void *" p ); |
149 | .fi |
150 | .PP |
151 | It is passed: |
1e7e4330 |
152 | .TP |
153 | .BI "octet *" b |
154 | A pointer to the packet data in the buffer, or zero to signify |
155 | end-of-file. |
156 | .TP |
157 | .BI "size_t " sz |
158 | The size of the packet, as previously configured via |
159 | .BR pkbuf_want . |
160 | .TP |
161 | .BI "pkbuf *" pk |
162 | A pointer to the packet buffer. |
163 | .TP |
164 | .BI "size_t *" keep |
165 | A location in which to store the number of bytes of the current packet |
166 | to be retained. The bytes kept are from the end of the current packet: |
167 | if you want to keep bytes from the beginning of the packet, you should |
168 | move them into the right place. |
169 | .TP |
170 | .BI "void *" p |
171 | The pointer which was set up in the call to |
172 | .BR pkbuf_init . |
173 | .PP |
174 | .SS "Flushing the remaining data" |
175 | When the client program knows that there's no more data arriving (for |
176 | example, an end-of-file condition exists on its data source) it should |
177 | call the function |
178 | .BR pkbuf_close . |
179 | This will call the handler one final time with a null pointer to inform |
180 | it of the end-of-file. |
181 | .SS "Disablement" |
182 | The packet buffer is intended to be used in higher-level program |
183 | objects, such as the packet selector described in |
184 | .BR selpk (3). |
185 | Unfortunately, a concept from this high level needs to exist at the |
186 | packet buffer level, which complicates the description somewhat. The |
187 | idea is that, when a packet-handler attached to some higher-level object |
188 | decides that it's read enough, it can |
189 | .I disable |
190 | the object so that it doesn't see any more data. |
191 | .PP |
192 | Clearly, since an |
193 | .B pkbuf_flush |
528c8b4d |
194 | call can emit more than one packet, it must be aware that the packet |
1e7e4330 |
195 | handler isn't interested in any more packet. However, this fact must |
196 | also be signalled to the higher-level object so that it can detach |
197 | itself from its data source. |
198 | .PP |
199 | Rather than invent some complex interface for this, the packet buffer |
3bc42912 |
200 | exports one of its structure members, a flags words called |
201 | .BR f . |
1e7e4330 |
202 | A higher-level object wishing to disable the packet buffer simply clears |
203 | the bit |
204 | .B PKBUF_ENABLE |
3bc42912 |
205 | in this flags word. |
1e7e4330 |
206 | .PP |
207 | Disabling a buffer causes an immediate return from |
208 | .BR pkbuf_flush . |
209 | However, it is not permitted for the functions |
210 | .B pkbuf_flush |
211 | or |
212 | .B pkbuf_close |
213 | to be called on a disabled buffer. (This condition isn't checked for; |
214 | it'll just do the wrong thing.) Furthermore, the |
215 | .B pkbuf_snarf |
216 | function does not handle disablement at all, because it would complicate |
217 | the interface so much that it wouldn't have any advantage over the more |
218 | general |
219 | .BR pkbuf_free / pkbuf_flush . |
220 | .SH "SEE ALSO" |
221 | .BR lbuf (3), |
222 | .BR selpk (3), |
223 | .BR mLib (3). |
224 | .SH "AUTHOR" |
9b5ac6ff |
225 | Mark Wooding, <mdw@distorted.org.uk> |