1 056fe1ba 2003-11-23 devnull #include <u.h>
2 056fe1ba 2003-11-23 devnull #include <libc.h>
3 056fe1ba 2003-11-23 devnull #include <venti.h>
4 056fe1ba 2003-11-23 devnull #include <libsec.h>
6 056fe1ba 2003-11-23 devnull typedef struct Mem Mem;
7 056fe1ba 2003-11-23 devnull typedef struct Frag Frag;
10 056fe1ba 2003-11-23 devnull BigMemSize = MaxFragSize,
11 056fe1ba 2003-11-23 devnull SmallMemSize = BigMemSize/8,
12 056fe1ba 2003-11-23 devnull NLocalFrag = 2,
15 056fe1ba 2003-11-23 devnull /* position to carve out of a Mem */
22 056fe1ba 2003-11-23 devnull struct Mem
26 056fe1ba 2003-11-23 devnull uchar *bp;
27 056fe1ba 2003-11-23 devnull uchar *ep;
28 056fe1ba 2003-11-23 devnull uchar *rp;
29 056fe1ba 2003-11-23 devnull uchar *wp;
30 056fe1ba 2003-11-23 devnull Mem *next;
34 056fe1ba 2003-11-23 devnull FragLocalFree,
35 056fe1ba 2003-11-23 devnull FragLocalAlloc,
36 056fe1ba 2003-11-23 devnull FragGlobal,
39 056fe1ba 2003-11-23 devnull struct Frag
41 056fe1ba 2003-11-23 devnull int state;
42 056fe1ba 2003-11-23 devnull Mem *mem;
43 056fe1ba 2003-11-23 devnull uchar *rp;
44 056fe1ba 2003-11-23 devnull uchar *wp;
45 056fe1ba 2003-11-23 devnull Frag *next;
46 056fe1ba 2003-11-23 devnull void (*free)(void*);
50 056fe1ba 2003-11-23 devnull struct Packet
52 056fe1ba 2003-11-23 devnull int size;
53 056fe1ba 2003-11-23 devnull int asize; /* allocated memory - greater than size unless foreign frags */
55 056fe1ba 2003-11-23 devnull Packet *next;
57 056fe1ba 2003-11-23 devnull Frag *first;
58 056fe1ba 2003-11-23 devnull Frag *last;
60 056fe1ba 2003-11-23 devnull Frag local[NLocalFrag];
63 056fe1ba 2003-11-23 devnull static Frag *fragalloc(Packet*, int n, int pos, Frag *next);
64 056fe1ba 2003-11-23 devnull static Frag *fragdup(Packet*, Frag*);
65 056fe1ba 2003-11-23 devnull static void fragfree(Frag*);
67 056fe1ba 2003-11-23 devnull static Mem *memalloc(int, int);
68 056fe1ba 2003-11-23 devnull static void memfree(Mem*);
69 056fe1ba 2003-11-23 devnull static int memhead(Mem *m, uchar *rp, int n);
70 056fe1ba 2003-11-23 devnull static int memtail(Mem *m, uchar *wp, int n);
72 056fe1ba 2003-11-23 devnull static char EPacketSize[] = "bad packet size";
73 056fe1ba 2003-11-23 devnull static char EPacketOffset[] = "bad packet offset";
74 056fe1ba 2003-11-23 devnull static char EBadSize[] = "bad size";
76 056fe1ba 2003-11-23 devnull static struct {
78 056fe1ba 2003-11-23 devnull Packet *packet;
79 056fe1ba 2003-11-23 devnull int npacket;
80 056fe1ba 2003-11-23 devnull Frag *frag;
81 056fe1ba 2003-11-23 devnull int nfrag;
82 056fe1ba 2003-11-23 devnull Mem *bigmem;
83 056fe1ba 2003-11-23 devnull int nbigmem;
84 056fe1ba 2003-11-23 devnull Mem *smallmem;
85 056fe1ba 2003-11-23 devnull int nsmallmem;
86 056fe1ba 2003-11-23 devnull } freelist;
88 056fe1ba 2003-11-23 devnull #define FRAGSIZE(f) ((f)->wp - (f)->rp)
89 056fe1ba 2003-11-23 devnull #define FRAGASIZE(f) ((f)->mem ? (f)->mem->ep - (f)->mem->bp : 0)
91 056fe1ba 2003-11-23 devnull #define NOTFREE(p) assert((p)->size>=0)
94 056fe1ba 2003-11-23 devnull packetalloc(void)
96 056fe1ba 2003-11-23 devnull Packet *p;
98 056fe1ba 2003-11-23 devnull lock(&freelist.lk);
99 056fe1ba 2003-11-23 devnull p = freelist.packet;
100 056fe1ba 2003-11-23 devnull if(p != nil)
101 056fe1ba 2003-11-23 devnull freelist.packet = p->next;
103 056fe1ba 2003-11-23 devnull freelist.npacket++;
104 056fe1ba 2003-11-23 devnull unlock(&freelist.lk);
106 056fe1ba 2003-11-23 devnull if(p == nil)
107 056fe1ba 2003-11-23 devnull p = vtbrk(sizeof(Packet));
109 056fe1ba 2003-11-23 devnull assert(p->size == -1);
110 056fe1ba 2003-11-23 devnull p->size = 0;
111 056fe1ba 2003-11-23 devnull p->asize = 0;
112 056fe1ba 2003-11-23 devnull p->first = nil;
113 056fe1ba 2003-11-23 devnull p->last = nil;
114 056fe1ba 2003-11-23 devnull p->next = nil;
116 056fe1ba 2003-11-23 devnull if(1)fprint(2, "packetalloc %p from %08lux %08lux %08lux\n", p, *((uint*)&p+2), *((uint*)&p+3), *((uint*)&p+4));
118 056fe1ba 2003-11-23 devnull return p;
122 056fe1ba 2003-11-23 devnull packetfree(Packet *p)
124 056fe1ba 2003-11-23 devnull Frag *f, *ff;
126 056fe1ba 2003-11-23 devnull if(1)fprint(2, "packetfree %p from %08lux\n", p, getcallerpc(&p));
128 056fe1ba 2003-11-23 devnull if(p == nil)
131 056fe1ba 2003-11-23 devnull NOTFREE(p);
132 056fe1ba 2003-11-23 devnull p->size = -1;
134 056fe1ba 2003-11-23 devnull for(f=p->first; f!=nil; f=ff) {
135 056fe1ba 2003-11-23 devnull ff = f->next;
136 056fe1ba 2003-11-23 devnull fragfree(f);
138 056fe1ba 2003-11-23 devnull p->first = nil;
139 056fe1ba 2003-11-23 devnull p->last = nil;
141 056fe1ba 2003-11-23 devnull lock(&freelist.lk);
142 056fe1ba 2003-11-23 devnull p->next = freelist.packet;
143 056fe1ba 2003-11-23 devnull freelist.packet = p;
144 056fe1ba 2003-11-23 devnull unlock(&freelist.lk);
147 056fe1ba 2003-11-23 devnull Packet *
148 056fe1ba 2003-11-23 devnull packetdup(Packet *p, int offset, int n)
150 056fe1ba 2003-11-23 devnull Frag *f, *ff;
151 056fe1ba 2003-11-23 devnull Packet *pp;
153 056fe1ba 2003-11-23 devnull NOTFREE(p);
154 056fe1ba 2003-11-23 devnull if(offset < 0 || n < 0 || offset+n > p->size) {
155 056fe1ba 2003-11-23 devnull werrstr(EBadSize);
156 056fe1ba 2003-11-23 devnull return nil;
159 056fe1ba 2003-11-23 devnull pp = packetalloc();
160 056fe1ba 2003-11-23 devnull if(n == 0)
161 056fe1ba 2003-11-23 devnull return pp;
163 056fe1ba 2003-11-23 devnull pp->size = n;
165 056fe1ba 2003-11-23 devnull /* skip offset */
166 056fe1ba 2003-11-23 devnull for(f=p->first; offset >= FRAGSIZE(f); f=f->next)
167 056fe1ba 2003-11-23 devnull offset -= FRAGSIZE(f);
169 056fe1ba 2003-11-23 devnull /* first frag */
170 056fe1ba 2003-11-23 devnull ff = fragdup(pp, f);
171 056fe1ba 2003-11-23 devnull ff->rp += offset;
172 056fe1ba 2003-11-23 devnull pp->first = ff;
173 056fe1ba 2003-11-23 devnull n -= FRAGSIZE(ff);
174 056fe1ba 2003-11-23 devnull pp->asize += FRAGASIZE(ff);
176 056fe1ba 2003-11-23 devnull /* the remaining */
177 056fe1ba 2003-11-23 devnull while(n > 0) {
178 056fe1ba 2003-11-23 devnull f = f->next;
179 056fe1ba 2003-11-23 devnull ff->next = fragdup(pp, f);
180 056fe1ba 2003-11-23 devnull ff = ff->next;
181 056fe1ba 2003-11-23 devnull n -= FRAGSIZE(ff);
182 056fe1ba 2003-11-23 devnull pp->asize += FRAGASIZE(ff);
185 056fe1ba 2003-11-23 devnull /* fix up last frag: note n <= 0 */
186 056fe1ba 2003-11-23 devnull ff->wp += n;
187 056fe1ba 2003-11-23 devnull ff->next = nil;
188 056fe1ba 2003-11-23 devnull pp->last = ff;
190 056fe1ba 2003-11-23 devnull return pp;
193 056fe1ba 2003-11-23 devnull Packet *
194 056fe1ba 2003-11-23 devnull packetsplit(Packet *p, int n)
196 056fe1ba 2003-11-23 devnull Packet *pp;
197 056fe1ba 2003-11-23 devnull Frag *f, *ff;
199 056fe1ba 2003-11-23 devnull NOTFREE(p);
200 056fe1ba 2003-11-23 devnull if(n < 0 || n > p->size) {
201 056fe1ba 2003-11-23 devnull werrstr(EPacketSize);
202 056fe1ba 2003-11-23 devnull return nil;
205 056fe1ba 2003-11-23 devnull pp = packetalloc();
206 056fe1ba 2003-11-23 devnull if(n == 0)
207 056fe1ba 2003-11-23 devnull return pp;
209 056fe1ba 2003-11-23 devnull pp->size = n;
210 056fe1ba 2003-11-23 devnull p->size -= n;
211 056fe1ba 2003-11-23 devnull ff = nil;
212 056fe1ba 2003-11-23 devnull for(f=p->first; n > 0 && n >= FRAGSIZE(f); f=f->next) {
213 056fe1ba 2003-11-23 devnull n -= FRAGSIZE(f);
214 056fe1ba 2003-11-23 devnull p->asize -= FRAGASIZE(f);
215 056fe1ba 2003-11-23 devnull pp->asize += FRAGASIZE(f);
219 056fe1ba 2003-11-23 devnull /* split shared frag */
220 056fe1ba 2003-11-23 devnull if(n > 0) {
222 056fe1ba 2003-11-23 devnull f = fragdup(pp, ff);
223 056fe1ba 2003-11-23 devnull pp->asize += FRAGASIZE(ff);
224 056fe1ba 2003-11-23 devnull ff->next = nil;
225 056fe1ba 2003-11-23 devnull ff->wp = ff->rp + n;
226 056fe1ba 2003-11-23 devnull f->rp += n;
229 056fe1ba 2003-11-23 devnull pp->first = p->first;
230 056fe1ba 2003-11-23 devnull pp->last = ff;
231 056fe1ba 2003-11-23 devnull p->first = f;
232 056fe1ba 2003-11-23 devnull return pp;
236 056fe1ba 2003-11-23 devnull packetconsume(Packet *p, uchar *buf, int n)
238 056fe1ba 2003-11-23 devnull NOTFREE(p);
239 056fe1ba 2003-11-23 devnull if(buf && packetcopy(p, buf, 0, n) < 0)
240 056fe1ba 2003-11-23 devnull return 0;
241 056fe1ba 2003-11-23 devnull return packettrim(p, n, p->size-n);
245 056fe1ba 2003-11-23 devnull packettrim(Packet *p, int offset, int n)
247 056fe1ba 2003-11-23 devnull Frag *f, *ff;
249 056fe1ba 2003-11-23 devnull NOTFREE(p);
250 056fe1ba 2003-11-23 devnull if(offset < 0 || offset > p->size) {
251 056fe1ba 2003-11-23 devnull werrstr(EPacketOffset);
252 056fe1ba 2003-11-23 devnull return -1;
255 056fe1ba 2003-11-23 devnull if(n < 0 || offset + n > p->size) {
256 056fe1ba 2003-11-23 devnull werrstr(EPacketOffset);
257 056fe1ba 2003-11-23 devnull return -1;
260 056fe1ba 2003-11-23 devnull p->size = n;
262 056fe1ba 2003-11-23 devnull /* easy case */
263 056fe1ba 2003-11-23 devnull if(n == 0) {
264 056fe1ba 2003-11-23 devnull for(f=p->first; f != nil; f=ff) {
265 056fe1ba 2003-11-23 devnull ff = f->next;
266 056fe1ba 2003-11-23 devnull fragfree(f);
268 056fe1ba 2003-11-23 devnull p->first = p->last = nil;
269 056fe1ba 2003-11-23 devnull p->asize = 0;
270 056fe1ba 2003-11-23 devnull return 0;
273 056fe1ba 2003-11-23 devnull /* free before offset */
274 056fe1ba 2003-11-23 devnull for(f=p->first; offset >= FRAGSIZE(f); f=ff) {
275 056fe1ba 2003-11-23 devnull p->asize -= FRAGASIZE(f);
276 056fe1ba 2003-11-23 devnull offset -= FRAGSIZE(f);
277 056fe1ba 2003-11-23 devnull ff = f->next;
278 056fe1ba 2003-11-23 devnull fragfree(f);
281 056fe1ba 2003-11-23 devnull /* adjust frag */
282 056fe1ba 2003-11-23 devnull f->rp += offset;
283 056fe1ba 2003-11-23 devnull p->first = f;
285 056fe1ba 2003-11-23 devnull /* skip middle */
286 056fe1ba 2003-11-23 devnull for(; n > 0 && n > FRAGSIZE(f); f=f->next)
287 056fe1ba 2003-11-23 devnull n -= FRAGSIZE(f);
289 056fe1ba 2003-11-23 devnull /* adjust end */
290 056fe1ba 2003-11-23 devnull f->wp = f->rp + n;
291 056fe1ba 2003-11-23 devnull p->last = f;
292 056fe1ba 2003-11-23 devnull ff = f->next;
293 056fe1ba 2003-11-23 devnull f->next = nil;
295 056fe1ba 2003-11-23 devnull /* free after */
296 056fe1ba 2003-11-23 devnull for(f=ff; f != nil; f=ff) {
297 056fe1ba 2003-11-23 devnull p->asize -= FRAGASIZE(f);
298 056fe1ba 2003-11-23 devnull ff = f->next;
299 056fe1ba 2003-11-23 devnull fragfree(f);
301 056fe1ba 2003-11-23 devnull return 0;
305 056fe1ba 2003-11-23 devnull packetheader(Packet *p, int n)
307 056fe1ba 2003-11-23 devnull Frag *f;
310 056fe1ba 2003-11-23 devnull NOTFREE(p);
311 056fe1ba 2003-11-23 devnull if(n <= 0 || n > MaxFragSize) {
312 056fe1ba 2003-11-23 devnull werrstr(EPacketSize);
313 056fe1ba 2003-11-23 devnull return nil;
316 056fe1ba 2003-11-23 devnull p->size += n;
318 056fe1ba 2003-11-23 devnull /* try and fix in current frag */
319 056fe1ba 2003-11-23 devnull f = p->first;
320 056fe1ba 2003-11-23 devnull if(f != nil) {
321 056fe1ba 2003-11-23 devnull m = f->mem;
322 056fe1ba 2003-11-23 devnull if(n <= f->rp - m->bp)
323 056fe1ba 2003-11-23 devnull if(m->ref == 1 || memhead(m, f->rp, n) >= 0) {
324 056fe1ba 2003-11-23 devnull f->rp -= n;
325 056fe1ba 2003-11-23 devnull return f->rp;
329 056fe1ba 2003-11-23 devnull /* add frag to front */
330 056fe1ba 2003-11-23 devnull f = fragalloc(p, n, PEnd, p->first);
331 056fe1ba 2003-11-23 devnull p->asize += FRAGASIZE(f);
332 056fe1ba 2003-11-23 devnull if(p->first == nil)
333 056fe1ba 2003-11-23 devnull p->last = f;
334 056fe1ba 2003-11-23 devnull p->first = f;
335 056fe1ba 2003-11-23 devnull return f->rp;
339 056fe1ba 2003-11-23 devnull packettrailer(Packet *p, int n)
342 056fe1ba 2003-11-23 devnull Frag *f;
344 056fe1ba 2003-11-23 devnull NOTFREE(p);
345 056fe1ba 2003-11-23 devnull if(n <= 0 || n > MaxFragSize) {
346 056fe1ba 2003-11-23 devnull werrstr(EPacketSize);
347 056fe1ba 2003-11-23 devnull return nil;
350 056fe1ba 2003-11-23 devnull p->size += n;
352 056fe1ba 2003-11-23 devnull /* try and fix in current frag */
353 056fe1ba 2003-11-23 devnull if(p->first != nil) {
354 056fe1ba 2003-11-23 devnull f = p->last;
355 056fe1ba 2003-11-23 devnull m = f->mem;
356 056fe1ba 2003-11-23 devnull if(n <= m->ep - f->wp)
357 056fe1ba 2003-11-23 devnull if(m->ref == 1 || memtail(m, f->wp, n) >= 0) {
358 056fe1ba 2003-11-23 devnull f->wp += n;
359 056fe1ba 2003-11-23 devnull return f->wp - n;
363 056fe1ba 2003-11-23 devnull /* add frag to end */
364 056fe1ba 2003-11-23 devnull f = fragalloc(p, n, (p->first == nil)?PMiddle:PFront, nil);
365 056fe1ba 2003-11-23 devnull p->asize += FRAGASIZE(f);
366 056fe1ba 2003-11-23 devnull if(p->first == nil)
367 056fe1ba 2003-11-23 devnull p->first = f;
369 056fe1ba 2003-11-23 devnull p->last->next = f;
370 056fe1ba 2003-11-23 devnull p->last = f;
371 056fe1ba 2003-11-23 devnull return f->rp;
375 056fe1ba 2003-11-23 devnull packetprefix(Packet *p, uchar *buf, int n)
377 056fe1ba 2003-11-23 devnull Frag *f;
381 056fe1ba 2003-11-23 devnull NOTFREE(p);
382 056fe1ba 2003-11-23 devnull if(n <= 0)
383 056fe1ba 2003-11-23 devnull return 0;
385 056fe1ba 2003-11-23 devnull p->size += n;
387 056fe1ba 2003-11-23 devnull /* try and fix in current frag */
388 056fe1ba 2003-11-23 devnull f = p->first;
389 056fe1ba 2003-11-23 devnull if(f != nil) {
390 056fe1ba 2003-11-23 devnull m = f->mem;
391 056fe1ba 2003-11-23 devnull nn = f->rp - m->bp;
392 056fe1ba 2003-11-23 devnull if(nn > n)
394 056fe1ba 2003-11-23 devnull if(m->ref == 1 || memhead(m, f->rp, nn) >= 0) {
395 056fe1ba 2003-11-23 devnull f->rp -= nn;
396 056fe1ba 2003-11-23 devnull n -= nn;
397 056fe1ba 2003-11-23 devnull memmove(f->rp, buf+n, nn);
401 056fe1ba 2003-11-23 devnull while(n > 0) {
403 056fe1ba 2003-11-23 devnull if(nn > MaxFragSize)
404 056fe1ba 2003-11-23 devnull nn = MaxFragSize;
405 056fe1ba 2003-11-23 devnull f = fragalloc(p, nn, PEnd, p->first);
406 056fe1ba 2003-11-23 devnull p->asize += FRAGASIZE(f);
407 056fe1ba 2003-11-23 devnull if(p->first == nil)
408 056fe1ba 2003-11-23 devnull p->last = f;
409 056fe1ba 2003-11-23 devnull p->first = f;
410 056fe1ba 2003-11-23 devnull n -= nn;
411 056fe1ba 2003-11-23 devnull memmove(f->rp, buf+n, nn);
413 056fe1ba 2003-11-23 devnull return 0;
417 056fe1ba 2003-11-23 devnull packetappend(Packet *p, uchar *buf, int n)
419 056fe1ba 2003-11-23 devnull Frag *f;
423 056fe1ba 2003-11-23 devnull NOTFREE(p);
424 056fe1ba 2003-11-23 devnull if(n <= 0)
425 056fe1ba 2003-11-23 devnull return 0;
427 056fe1ba 2003-11-23 devnull p->size += n;
428 056fe1ba 2003-11-23 devnull /* try and fix in current frag */
429 056fe1ba 2003-11-23 devnull if(p->first != nil) {
430 056fe1ba 2003-11-23 devnull f = p->last;
431 056fe1ba 2003-11-23 devnull m = f->mem;
432 056fe1ba 2003-11-23 devnull nn = m->ep - f->wp;
433 056fe1ba 2003-11-23 devnull if(nn > n)
435 056fe1ba 2003-11-23 devnull if(m->ref == 1 || memtail(m, f->wp, nn) >= 0) {
436 056fe1ba 2003-11-23 devnull memmove(f->wp, buf, nn);
437 056fe1ba 2003-11-23 devnull f->wp += nn;
438 056fe1ba 2003-11-23 devnull buf += nn;
439 056fe1ba 2003-11-23 devnull n -= nn;
443 056fe1ba 2003-11-23 devnull while(n > 0) {
445 056fe1ba 2003-11-23 devnull if(nn > MaxFragSize)
446 056fe1ba 2003-11-23 devnull nn = MaxFragSize;
447 056fe1ba 2003-11-23 devnull f = fragalloc(p, nn, (p->first == nil)?PMiddle:PFront, nil);
448 056fe1ba 2003-11-23 devnull p->asize += FRAGASIZE(f);
449 056fe1ba 2003-11-23 devnull if(p->first == nil)
450 056fe1ba 2003-11-23 devnull p->first = f;
452 056fe1ba 2003-11-23 devnull p->last->next = f;
453 056fe1ba 2003-11-23 devnull p->last = f;
454 056fe1ba 2003-11-23 devnull memmove(f->rp, buf, nn);
455 056fe1ba 2003-11-23 devnull buf += nn;
456 056fe1ba 2003-11-23 devnull n -= nn;
458 056fe1ba 2003-11-23 devnull return 0;
462 056fe1ba 2003-11-23 devnull packetconcat(Packet *p, Packet *pp)
464 056fe1ba 2003-11-23 devnull NOTFREE(p);
465 056fe1ba 2003-11-23 devnull NOTFREE(pp);
466 056fe1ba 2003-11-23 devnull if(pp->size == 0)
467 056fe1ba 2003-11-23 devnull return 0;
468 056fe1ba 2003-11-23 devnull p->size += pp->size;
469 056fe1ba 2003-11-23 devnull p->asize += pp->asize;
471 056fe1ba 2003-11-23 devnull if(p->first != nil)
472 056fe1ba 2003-11-23 devnull p->last->next = pp->first;
474 056fe1ba 2003-11-23 devnull p->first = pp->first;
475 056fe1ba 2003-11-23 devnull p->last = pp->last;
476 056fe1ba 2003-11-23 devnull pp->size = 0;
477 056fe1ba 2003-11-23 devnull pp->asize = 0;
478 056fe1ba 2003-11-23 devnull pp->first = nil;
479 056fe1ba 2003-11-23 devnull pp->last = nil;
480 056fe1ba 2003-11-23 devnull return 0;
484 056fe1ba 2003-11-23 devnull packetpeek(Packet *p, uchar *buf, int offset, int n)
486 056fe1ba 2003-11-23 devnull Frag *f;
488 056fe1ba 2003-11-23 devnull uchar *b;
490 056fe1ba 2003-11-23 devnull NOTFREE(p);
491 056fe1ba 2003-11-23 devnull if(n == 0)
492 056fe1ba 2003-11-23 devnull return buf;
494 056fe1ba 2003-11-23 devnull if(offset < 0 || offset >= p->size) {
495 056fe1ba 2003-11-23 devnull werrstr(EPacketOffset);
496 056fe1ba 2003-11-23 devnull return nil;
499 056fe1ba 2003-11-23 devnull if(n < 0 || offset + n > p->size) {
500 056fe1ba 2003-11-23 devnull werrstr(EPacketSize);
501 056fe1ba 2003-11-23 devnull return nil;
504 056fe1ba 2003-11-23 devnull /* skip up to offset */
505 056fe1ba 2003-11-23 devnull for(f=p->first; offset >= FRAGSIZE(f); f=f->next)
506 056fe1ba 2003-11-23 devnull offset -= FRAGSIZE(f);
508 056fe1ba 2003-11-23 devnull /* easy case */
509 056fe1ba 2003-11-23 devnull if(offset + n <= FRAGSIZE(f))
510 056fe1ba 2003-11-23 devnull return f->rp + offset;
512 056fe1ba 2003-11-23 devnull for(b=buf; n>0; n -= nn) {
513 056fe1ba 2003-11-23 devnull nn = FRAGSIZE(f) - offset;
514 056fe1ba 2003-11-23 devnull if(nn > n)
516 056fe1ba 2003-11-23 devnull memmove(b, f->rp+offset, nn);
517 056fe1ba 2003-11-23 devnull offset = 0;
518 056fe1ba 2003-11-23 devnull f = f->next;
519 056fe1ba 2003-11-23 devnull b += nn;
522 056fe1ba 2003-11-23 devnull return buf;
526 056fe1ba 2003-11-23 devnull packetcopy(Packet *p, uchar *buf, int offset, int n)
528 056fe1ba 2003-11-23 devnull uchar *b;
530 056fe1ba 2003-11-23 devnull NOTFREE(p);
531 056fe1ba 2003-11-23 devnull b = packetpeek(p, buf, offset, n);
532 056fe1ba 2003-11-23 devnull if(b == nil)
533 056fe1ba 2003-11-23 devnull return -1;
534 056fe1ba 2003-11-23 devnull if(b != buf)
535 056fe1ba 2003-11-23 devnull memmove(buf, b, n);
536 056fe1ba 2003-11-23 devnull return 0;
540 056fe1ba 2003-11-23 devnull packetfragments(Packet *p, IOchunk *io, int nio, int offset)
542 056fe1ba 2003-11-23 devnull Frag *f;
543 056fe1ba 2003-11-23 devnull int size;
544 056fe1ba 2003-11-23 devnull IOchunk *eio;
546 056fe1ba 2003-11-23 devnull NOTFREE(p);
547 056fe1ba 2003-11-23 devnull if(p->size == 0 || nio <= 0)
548 056fe1ba 2003-11-23 devnull return 0;
550 056fe1ba 2003-11-23 devnull if(offset < 0 || offset > p->size) {
551 056fe1ba 2003-11-23 devnull werrstr(EPacketOffset);
552 056fe1ba 2003-11-23 devnull return -1;
555 056fe1ba 2003-11-23 devnull for(f=p->first; offset >= FRAGSIZE(f); f=f->next)
556 056fe1ba 2003-11-23 devnull offset -= FRAGSIZE(f);
558 056fe1ba 2003-11-23 devnull size = 0;
559 056fe1ba 2003-11-23 devnull eio = io + nio;
560 056fe1ba 2003-11-23 devnull for(; f != nil && io < eio; f=f->next) {
561 056fe1ba 2003-11-23 devnull io->addr = f->rp + offset;
562 056fe1ba 2003-11-23 devnull io->len = f->wp - (f->rp + offset);
563 056fe1ba 2003-11-23 devnull offset = 0;
564 056fe1ba 2003-11-23 devnull size += io->len;
568 056fe1ba 2003-11-23 devnull return size;
572 056fe1ba 2003-11-23 devnull packetstats(void)
574 056fe1ba 2003-11-23 devnull Packet *p;
575 056fe1ba 2003-11-23 devnull Frag *f;
578 056fe1ba 2003-11-23 devnull int np, nf, nsm, nbm;
580 056fe1ba 2003-11-23 devnull lock(&freelist.lk);
582 056fe1ba 2003-11-23 devnull for(p=freelist.packet; p; p=p->next)
585 056fe1ba 2003-11-23 devnull for(f=freelist.frag; f; f=f->next)
587 056fe1ba 2003-11-23 devnull nsm = 0;
588 056fe1ba 2003-11-23 devnull for(m=freelist.smallmem; m; m=m->next)
590 056fe1ba 2003-11-23 devnull nbm = 0;
591 056fe1ba 2003-11-23 devnull for(m=freelist.bigmem; m; m=m->next)
594 056fe1ba 2003-11-23 devnull fprint(2, "packet: %d/%d frag: %d/%d small mem: %d/%d big mem: %d/%d\n",
595 056fe1ba 2003-11-23 devnull np, freelist.npacket,
596 056fe1ba 2003-11-23 devnull nf, freelist.nfrag,
597 056fe1ba 2003-11-23 devnull nsm, freelist.nsmallmem,
598 056fe1ba 2003-11-23 devnull nbm, freelist.nbigmem);
600 056fe1ba 2003-11-23 devnull unlock(&freelist.lk);
605 056fe1ba 2003-11-23 devnull packetsize(Packet *p)
607 056fe1ba 2003-11-23 devnull NOTFREE(p);
609 056fe1ba 2003-11-23 devnull Frag *f;
610 056fe1ba 2003-11-23 devnull int size = 0;
612 056fe1ba 2003-11-23 devnull for(f=p->first; f; f=f->next)
613 056fe1ba 2003-11-23 devnull size += FRAGSIZE(f);
614 056fe1ba 2003-11-23 devnull if(size != p->size)
615 056fe1ba 2003-11-23 devnull fprint(2, "packetsize %d %d\n", size, p->size);
616 056fe1ba 2003-11-23 devnull assert(size == p->size);
618 056fe1ba 2003-11-23 devnull return p->size;
622 056fe1ba 2003-11-23 devnull packetasize(Packet *p)
624 056fe1ba 2003-11-23 devnull NOTFREE(p);
626 056fe1ba 2003-11-23 devnull Frag *f;
627 056fe1ba 2003-11-23 devnull int asize = 0;
629 056fe1ba 2003-11-23 devnull for(f=p->first; f; f=f->next)
630 056fe1ba 2003-11-23 devnull asize += FRAGASIZE(f);
631 056fe1ba 2003-11-23 devnull if(asize != p->asize)
632 056fe1ba 2003-11-23 devnull fprint(2, "packetasize %d %d\n", asize, p->asize);
633 056fe1ba 2003-11-23 devnull assert(asize == p->asize);
635 056fe1ba 2003-11-23 devnull return p->asize;
639 056fe1ba 2003-11-23 devnull packetsha1(Packet *p, uchar digest[VtScoreSize])
641 056fe1ba 2003-11-23 devnull DigestState ds;
642 056fe1ba 2003-11-23 devnull Frag *f;
643 056fe1ba 2003-11-23 devnull int size;
645 056fe1ba 2003-11-23 devnull NOTFREE(p);
646 056fe1ba 2003-11-23 devnull memset(&ds, 0, sizeof ds);
647 056fe1ba 2003-11-23 devnull size = p->size;
648 056fe1ba 2003-11-23 devnull for(f=p->first; f; f=f->next) {
649 056fe1ba 2003-11-23 devnull sha1(f->rp, FRAGSIZE(f), nil, &ds);
650 056fe1ba 2003-11-23 devnull size -= FRAGSIZE(f);
652 056fe1ba 2003-11-23 devnull assert(size == 0);
653 056fe1ba 2003-11-23 devnull sha1(nil, 0, digest, &ds);
657 056fe1ba 2003-11-23 devnull packetcmp(Packet *pkt0, Packet *pkt1)
659 056fe1ba 2003-11-23 devnull Frag *f0, *f1;
660 056fe1ba 2003-11-23 devnull int n0, n1, x;
662 056fe1ba 2003-11-23 devnull NOTFREE(pkt0);
663 056fe1ba 2003-11-23 devnull NOTFREE(pkt1);
664 056fe1ba 2003-11-23 devnull f0 = pkt0->first;
665 056fe1ba 2003-11-23 devnull f1 = pkt1->first;
667 056fe1ba 2003-11-23 devnull if(f0 == nil)
668 056fe1ba 2003-11-23 devnull return (f1 == nil)?0:-1;
669 056fe1ba 2003-11-23 devnull if(f1 == nil)
670 056fe1ba 2003-11-23 devnull return 1;
671 056fe1ba 2003-11-23 devnull n0 = FRAGSIZE(f0);
672 056fe1ba 2003-11-23 devnull n1 = FRAGSIZE(f1);
674 056fe1ba 2003-11-23 devnull for(;;) {
675 056fe1ba 2003-11-23 devnull if(n0 < n1) {
676 056fe1ba 2003-11-23 devnull x = memcmp(f0->wp - n0, f1->wp - n1, n0);
677 056fe1ba 2003-11-23 devnull if(x != 0)
678 056fe1ba 2003-11-23 devnull return x;
679 056fe1ba 2003-11-23 devnull n1 -= n0;
680 056fe1ba 2003-11-23 devnull f0 = f0->next;
681 056fe1ba 2003-11-23 devnull if(f0 == nil)
682 056fe1ba 2003-11-23 devnull return -1;
683 056fe1ba 2003-11-23 devnull n0 = FRAGSIZE(f0);
684 056fe1ba 2003-11-23 devnull } else if (n0 > n1) {
685 056fe1ba 2003-11-23 devnull x = memcmp(f0->wp - n0, f1->wp - n1, n1);
686 056fe1ba 2003-11-23 devnull if(x != 0)
687 056fe1ba 2003-11-23 devnull return x;
688 056fe1ba 2003-11-23 devnull n0 -= n1;
689 056fe1ba 2003-11-23 devnull f1 = f1->next;
690 056fe1ba 2003-11-23 devnull if(f1 == nil)
691 056fe1ba 2003-11-23 devnull return 1;
692 056fe1ba 2003-11-23 devnull n1 = FRAGSIZE(f1);
693 056fe1ba 2003-11-23 devnull } else { /* n0 == n1 */
694 056fe1ba 2003-11-23 devnull x = memcmp(f0->wp - n0, f1->wp - n1, n0);
695 056fe1ba 2003-11-23 devnull if(x != 0)
696 056fe1ba 2003-11-23 devnull return x;
697 056fe1ba 2003-11-23 devnull f0 = f0->next;
698 056fe1ba 2003-11-23 devnull f1 = f1->next;
699 056fe1ba 2003-11-23 devnull if(f0 == nil)
700 056fe1ba 2003-11-23 devnull return (f1 == nil)?0:-1;
701 056fe1ba 2003-11-23 devnull if(f1 == nil)
702 056fe1ba 2003-11-23 devnull return 1;
703 056fe1ba 2003-11-23 devnull n0 = FRAGSIZE(f0);
704 056fe1ba 2003-11-23 devnull n1 = FRAGSIZE(f1);
707 056fe1ba 2003-11-23 devnull return 0; /* for ken */
711 056fe1ba 2003-11-23 devnull static Frag *
712 056fe1ba 2003-11-23 devnull fragalloc(Packet *p, int n, int pos, Frag *next)
714 056fe1ba 2003-11-23 devnull Frag *f, *ef;
717 056fe1ba 2003-11-23 devnull /* look for local frag */
718 056fe1ba 2003-11-23 devnull f = &p->local[0];
719 056fe1ba 2003-11-23 devnull ef = &p->local[NLocalFrag];
720 056fe1ba 2003-11-23 devnull for(;f<ef; f++) {
721 056fe1ba 2003-11-23 devnull if(f->state == FragLocalFree) {
722 056fe1ba 2003-11-23 devnull f->state = FragLocalAlloc;
723 056fe1ba 2003-11-23 devnull goto Found;
726 056fe1ba 2003-11-23 devnull lock(&freelist.lk);
727 056fe1ba 2003-11-23 devnull f = freelist.frag;
728 056fe1ba 2003-11-23 devnull if(f != nil)
729 056fe1ba 2003-11-23 devnull freelist.frag = f->next;
731 056fe1ba 2003-11-23 devnull freelist.nfrag++;
732 056fe1ba 2003-11-23 devnull unlock(&freelist.lk);
734 056fe1ba 2003-11-23 devnull if(f == nil) {
735 056fe1ba 2003-11-23 devnull f = vtbrk(sizeof(Frag));
736 056fe1ba 2003-11-23 devnull f->state = FragGlobal;
740 056fe1ba 2003-11-23 devnull f->next = next;
742 056fe1ba 2003-11-23 devnull if(n == 0){
743 056fe1ba 2003-11-23 devnull f->mem = 0;
744 056fe1ba 2003-11-23 devnull f->rp = 0;
745 056fe1ba 2003-11-23 devnull f->wp = 0;
746 056fe1ba 2003-11-23 devnull return f;
749 056fe1ba 2003-11-23 devnull if(pos == PEnd && next == nil)
750 056fe1ba 2003-11-23 devnull pos = PMiddle;
751 056fe1ba 2003-11-23 devnull m = memalloc(n, pos);
752 056fe1ba 2003-11-23 devnull f->mem = m;
753 056fe1ba 2003-11-23 devnull f->rp = m->rp;
754 056fe1ba 2003-11-23 devnull f->wp = m->wp;
755 056fe1ba 2003-11-23 devnull return f;
759 056fe1ba 2003-11-23 devnull packetforeign(uchar *buf, int n, void (*free)(void *a), void *a)
761 056fe1ba 2003-11-23 devnull Packet *p;
762 056fe1ba 2003-11-23 devnull Frag *f;
764 056fe1ba 2003-11-23 devnull p = packetalloc();
765 056fe1ba 2003-11-23 devnull f = fragalloc(p, 0, 0, nil);
766 056fe1ba 2003-11-23 devnull f->free = free;
767 056fe1ba 2003-11-23 devnull f->a = a;
768 056fe1ba 2003-11-23 devnull f->next = nil;
769 056fe1ba 2003-11-23 devnull f->rp = buf;
770 056fe1ba 2003-11-23 devnull f->wp = buf+n;
772 056fe1ba 2003-11-23 devnull p->first = f;
773 056fe1ba 2003-11-23 devnull p->size = n;
774 056fe1ba 2003-11-23 devnull return p;
777 056fe1ba 2003-11-23 devnull static Frag *
778 056fe1ba 2003-11-23 devnull fragdup(Packet *p, Frag *f)
780 056fe1ba 2003-11-23 devnull Frag *ff;
783 056fe1ba 2003-11-23 devnull m = f->mem;
786 056fe1ba 2003-11-23 devnull * m->rp && m->wp can be out of date when ref == 1
787 056fe1ba 2003-11-23 devnull * also, potentially reclaims space from previous frags
789 056fe1ba 2003-11-23 devnull if(m && m->ref == 1) {
790 056fe1ba 2003-11-23 devnull m->rp = f->rp;
791 056fe1ba 2003-11-23 devnull m->wp = f->wp;
794 056fe1ba 2003-11-23 devnull ff = fragalloc(p, 0, 0, nil);
795 056fe1ba 2003-11-23 devnull *ff = *f;
797 056fe1ba 2003-11-23 devnull lock(&m->lk);
798 056fe1ba 2003-11-23 devnull m->ref++;
799 056fe1ba 2003-11-23 devnull unlock(&m->lk);
801 056fe1ba 2003-11-23 devnull return ff;
805 056fe1ba 2003-11-23 devnull static void
806 056fe1ba 2003-11-23 devnull fragfree(Frag *f)
808 056fe1ba 2003-11-23 devnull if(f->mem == nil){
809 056fe1ba 2003-11-23 devnull if(f->free)
810 056fe1ba 2003-11-23 devnull (*f->free)(f->a);
812 056fe1ba 2003-11-23 devnull memfree(f->mem);
813 056fe1ba 2003-11-23 devnull f->mem = 0;
816 056fe1ba 2003-11-23 devnull if(f->state == FragLocalAlloc) {
817 056fe1ba 2003-11-23 devnull f->state = FragLocalFree;
821 056fe1ba 2003-11-23 devnull lock(&freelist.lk);
822 056fe1ba 2003-11-23 devnull f->next = freelist.frag;
823 056fe1ba 2003-11-23 devnull freelist.frag = f;
824 056fe1ba 2003-11-23 devnull unlock(&freelist.lk);
827 056fe1ba 2003-11-23 devnull static Mem *
828 056fe1ba 2003-11-23 devnull memalloc(int n, int pos)
833 056fe1ba 2003-11-23 devnull if(n < 0 || n > MaxFragSize) {
834 056fe1ba 2003-11-23 devnull werrstr(EPacketSize);
835 056fe1ba 2003-11-23 devnull return 0;
837 056fe1ba 2003-11-23 devnull if(n <= SmallMemSize) {
838 056fe1ba 2003-11-23 devnull lock(&freelist.lk);
839 056fe1ba 2003-11-23 devnull m = freelist.smallmem;
840 056fe1ba 2003-11-23 devnull if(m != nil)
841 056fe1ba 2003-11-23 devnull freelist.smallmem = m->next;
843 056fe1ba 2003-11-23 devnull freelist.nsmallmem++;
844 056fe1ba 2003-11-23 devnull unlock(&freelist.lk);
845 056fe1ba 2003-11-23 devnull nn = SmallMemSize;
846 056fe1ba 2003-11-23 devnull } else {
847 056fe1ba 2003-11-23 devnull lock(&freelist.lk);
848 056fe1ba 2003-11-23 devnull m = freelist.bigmem;
849 056fe1ba 2003-11-23 devnull if(m != nil)
850 056fe1ba 2003-11-23 devnull freelist.bigmem = m->next;
852 056fe1ba 2003-11-23 devnull freelist.nbigmem++;
853 056fe1ba 2003-11-23 devnull unlock(&freelist.lk);
854 056fe1ba 2003-11-23 devnull nn = BigMemSize;
857 056fe1ba 2003-11-23 devnull if(m == nil) {
858 056fe1ba 2003-11-23 devnull m = vtbrk(sizeof(Mem));
859 056fe1ba 2003-11-23 devnull m->bp = vtbrk(nn);
860 056fe1ba 2003-11-23 devnull m->ep = m->bp + nn;
862 056fe1ba 2003-11-23 devnull assert(m->ref == 0);
863 056fe1ba 2003-11-23 devnull m->ref = 1;
865 056fe1ba 2003-11-23 devnull switch(pos) {
866 056fe1ba 2003-11-23 devnull default:
867 056fe1ba 2003-11-23 devnull assert(0);
868 056fe1ba 2003-11-23 devnull case PFront:
869 056fe1ba 2003-11-23 devnull m->rp = m->bp;
871 056fe1ba 2003-11-23 devnull case PMiddle:
872 056fe1ba 2003-11-23 devnull /* leave a little bit at end */
873 056fe1ba 2003-11-23 devnull m->rp = m->ep - n - 32;
875 056fe1ba 2003-11-23 devnull case PEnd:
876 056fe1ba 2003-11-23 devnull m->rp = m->ep - n;
879 056fe1ba 2003-11-23 devnull /* check we did not blow it */
880 056fe1ba 2003-11-23 devnull if(m->rp < m->bp)
881 056fe1ba 2003-11-23 devnull m->rp = m->bp;
882 056fe1ba 2003-11-23 devnull m->wp = m->rp + n;
883 056fe1ba 2003-11-23 devnull assert(m->rp >= m->bp && m->wp <= m->ep);
884 056fe1ba 2003-11-23 devnull return m;
887 056fe1ba 2003-11-23 devnull static void
888 056fe1ba 2003-11-23 devnull memfree(Mem *m)
890 056fe1ba 2003-11-23 devnull lock(&m->lk);
891 056fe1ba 2003-11-23 devnull m->ref--;
892 056fe1ba 2003-11-23 devnull if(m->ref > 0) {
893 056fe1ba 2003-11-23 devnull unlock(&m->lk);
896 056fe1ba 2003-11-23 devnull unlock(&m->lk);
897 056fe1ba 2003-11-23 devnull assert(m->ref == 0);
899 056fe1ba 2003-11-23 devnull switch(m->ep - m->bp) {
900 056fe1ba 2003-11-23 devnull default:
901 056fe1ba 2003-11-23 devnull assert(0);
902 056fe1ba 2003-11-23 devnull case SmallMemSize:
903 056fe1ba 2003-11-23 devnull lock(&freelist.lk);
904 056fe1ba 2003-11-23 devnull m->next = freelist.smallmem;
905 056fe1ba 2003-11-23 devnull freelist.smallmem = m;
906 056fe1ba 2003-11-23 devnull unlock(&freelist.lk);
908 056fe1ba 2003-11-23 devnull case BigMemSize:
909 056fe1ba 2003-11-23 devnull lock(&freelist.lk);
910 056fe1ba 2003-11-23 devnull m->next = freelist.bigmem;
911 056fe1ba 2003-11-23 devnull freelist.bigmem = m;
912 056fe1ba 2003-11-23 devnull unlock(&freelist.lk);
917 056fe1ba 2003-11-23 devnull static int
918 056fe1ba 2003-11-23 devnull memhead(Mem *m, uchar *rp, int n)
920 056fe1ba 2003-11-23 devnull lock(&m->lk);
921 056fe1ba 2003-11-23 devnull if(m->rp != rp) {
922 056fe1ba 2003-11-23 devnull unlock(&m->lk);
923 056fe1ba 2003-11-23 devnull return -1;
925 056fe1ba 2003-11-23 devnull m->rp -= n;
926 056fe1ba 2003-11-23 devnull unlock(&m->lk);
927 056fe1ba 2003-11-23 devnull return 0;
930 056fe1ba 2003-11-23 devnull static int
931 056fe1ba 2003-11-23 devnull memtail(Mem *m, uchar *wp, int n)
933 056fe1ba 2003-11-23 devnull lock(&m->lk);
934 056fe1ba 2003-11-23 devnull if(m->wp != wp) {
935 056fe1ba 2003-11-23 devnull unlock(&m->lk);
936 056fe1ba 2003-11-23 devnull return -1;
938 056fe1ba 2003-11-23 devnull m->wp += n;
939 056fe1ba 2003-11-23 devnull unlock(&m->lk);
940 056fe1ba 2003-11-23 devnull return 0;