Blame


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>
5 056fe1ba 2003-11-23 devnull
6 056fe1ba 2003-11-23 devnull typedef struct Mem Mem;
7 056fe1ba 2003-11-23 devnull typedef struct Frag Frag;
8 056fe1ba 2003-11-23 devnull
9 056fe1ba 2003-11-23 devnull enum {
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,
13 056fe1ba 2003-11-23 devnull };
14 056fe1ba 2003-11-23 devnull
15 056fe1ba 2003-11-23 devnull /* position to carve out of a Mem */
16 056fe1ba 2003-11-23 devnull enum {
17 056fe1ba 2003-11-23 devnull PFront,
18 056fe1ba 2003-11-23 devnull PMiddle,
19 056fe1ba 2003-11-23 devnull PEnd,
20 056fe1ba 2003-11-23 devnull };
21 056fe1ba 2003-11-23 devnull
22 056fe1ba 2003-11-23 devnull struct Mem
23 056fe1ba 2003-11-23 devnull {
24 056fe1ba 2003-11-23 devnull Lock lk;
25 056fe1ba 2003-11-23 devnull int ref;
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;
31 056fe1ba 2003-11-23 devnull };
32 056fe1ba 2003-11-23 devnull
33 056fe1ba 2003-11-23 devnull enum {
34 056fe1ba 2003-11-23 devnull FragLocalFree,
35 056fe1ba 2003-11-23 devnull FragLocalAlloc,
36 056fe1ba 2003-11-23 devnull FragGlobal,
37 056fe1ba 2003-11-23 devnull };
38 056fe1ba 2003-11-23 devnull
39 056fe1ba 2003-11-23 devnull struct Frag
40 056fe1ba 2003-11-23 devnull {
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*);
47 056fe1ba 2003-11-23 devnull void *a;
48 8baa0cbd 2004-06-09 devnull Packet *p; /* parent packet, for debugging only */
49 056fe1ba 2003-11-23 devnull };
50 056fe1ba 2003-11-23 devnull
51 056fe1ba 2003-11-23 devnull struct Packet
52 056fe1ba 2003-11-23 devnull {
53 056fe1ba 2003-11-23 devnull int size;
54 056fe1ba 2003-11-23 devnull int asize; /* allocated memory - greater than size unless foreign frags */
55 8baa0cbd 2004-06-09 devnull ulong pc;
56 8baa0cbd 2004-06-09 devnull
57 056fe1ba 2003-11-23 devnull Packet *next;
58 056fe1ba 2003-11-23 devnull
59 056fe1ba 2003-11-23 devnull Frag *first;
60 056fe1ba 2003-11-23 devnull Frag *last;
61 056fe1ba 2003-11-23 devnull
62 056fe1ba 2003-11-23 devnull Frag local[NLocalFrag];
63 056fe1ba 2003-11-23 devnull };
64 056fe1ba 2003-11-23 devnull
65 056fe1ba 2003-11-23 devnull static Frag *fragalloc(Packet*, int n, int pos, Frag *next);
66 056fe1ba 2003-11-23 devnull static Frag *fragdup(Packet*, Frag*);
67 056fe1ba 2003-11-23 devnull static void fragfree(Frag*);
68 056fe1ba 2003-11-23 devnull
69 056fe1ba 2003-11-23 devnull static Mem *memalloc(int, int);
70 056fe1ba 2003-11-23 devnull static void memfree(Mem*);
71 056fe1ba 2003-11-23 devnull static int memhead(Mem *m, uchar *rp, int n);
72 056fe1ba 2003-11-23 devnull static int memtail(Mem *m, uchar *wp, int n);
73 056fe1ba 2003-11-23 devnull
74 056fe1ba 2003-11-23 devnull static char EPacketSize[] = "bad packet size";
75 056fe1ba 2003-11-23 devnull static char EPacketOffset[] = "bad packet offset";
76 056fe1ba 2003-11-23 devnull static char EBadSize[] = "bad size";
77 056fe1ba 2003-11-23 devnull
78 e5d47e6e 2004-12-28 devnull #if 0
79 8baa0cbd 2004-06-09 devnull static void checkpacket(Packet*);
80 e5d47e6e 2004-12-28 devnull #endif
81 8baa0cbd 2004-06-09 devnull
82 8baa0cbd 2004-06-09 devnull /*
83 8baa0cbd 2004-06-09 devnull * the free list is primarily for speed, but it is
84 8baa0cbd 2004-06-09 devnull * also necessary for packetsplit that packets
85 8baa0cbd 2004-06-09 devnull * are never freed -- a packet can contain a different
86 8baa0cbd 2004-06-09 devnull * packet's local fragments, thanks to packetsplit!
87 8baa0cbd 2004-06-09 devnull */
88 056fe1ba 2003-11-23 devnull static struct {
89 056fe1ba 2003-11-23 devnull Lock lk;
90 056fe1ba 2003-11-23 devnull Packet *packet;
91 056fe1ba 2003-11-23 devnull int npacket;
92 056fe1ba 2003-11-23 devnull Frag *frag;
93 056fe1ba 2003-11-23 devnull int nfrag;
94 056fe1ba 2003-11-23 devnull Mem *bigmem;
95 056fe1ba 2003-11-23 devnull int nbigmem;
96 056fe1ba 2003-11-23 devnull Mem *smallmem;
97 056fe1ba 2003-11-23 devnull int nsmallmem;
98 056fe1ba 2003-11-23 devnull } freelist;
99 056fe1ba 2003-11-23 devnull
100 056fe1ba 2003-11-23 devnull #define FRAGSIZE(f) ((f)->wp - (f)->rp)
101 056fe1ba 2003-11-23 devnull #define FRAGASIZE(f) ((f)->mem ? (f)->mem->ep - (f)->mem->bp : 0)
102 056fe1ba 2003-11-23 devnull
103 8baa0cbd 2004-06-09 devnull #define NOTFREE(p) assert((p)->size>=0)/*; checkpacket(p)*/
104 056fe1ba 2003-11-23 devnull
105 056fe1ba 2003-11-23 devnull Packet *
106 056fe1ba 2003-11-23 devnull packetalloc(void)
107 056fe1ba 2003-11-23 devnull {
108 056fe1ba 2003-11-23 devnull Packet *p;
109 056fe1ba 2003-11-23 devnull
110 056fe1ba 2003-11-23 devnull lock(&freelist.lk);
111 056fe1ba 2003-11-23 devnull p = freelist.packet;
112 056fe1ba 2003-11-23 devnull if(p != nil)
113 056fe1ba 2003-11-23 devnull freelist.packet = p->next;
114 056fe1ba 2003-11-23 devnull else
115 056fe1ba 2003-11-23 devnull freelist.npacket++;
116 056fe1ba 2003-11-23 devnull unlock(&freelist.lk);
117 056fe1ba 2003-11-23 devnull
118 056fe1ba 2003-11-23 devnull if(p == nil)
119 056fe1ba 2003-11-23 devnull p = vtbrk(sizeof(Packet));
120 056fe1ba 2003-11-23 devnull else
121 056fe1ba 2003-11-23 devnull assert(p->size == -1);
122 056fe1ba 2003-11-23 devnull p->size = 0;
123 056fe1ba 2003-11-23 devnull p->asize = 0;
124 056fe1ba 2003-11-23 devnull p->first = nil;
125 056fe1ba 2003-11-23 devnull p->last = nil;
126 056fe1ba 2003-11-23 devnull p->next = nil;
127 8baa0cbd 2004-06-09 devnull p->pc = getcallerpc((char*)&p+8); /* might not work, but fine */
128 056fe1ba 2003-11-23 devnull
129 a09e80f9 2004-05-23 devnull //if(0)fprint(2, "packetalloc %p from %08lux %08lux %08lux\n", p, *((uint*)&p+2), *((uint*)&p+3), *((uint*)&p+4));
130 056fe1ba 2003-11-23 devnull
131 8baa0cbd 2004-06-09 devnull NOTFREE(p);
132 056fe1ba 2003-11-23 devnull return p;
133 056fe1ba 2003-11-23 devnull }
134 056fe1ba 2003-11-23 devnull
135 056fe1ba 2003-11-23 devnull void
136 056fe1ba 2003-11-23 devnull packetfree(Packet *p)
137 056fe1ba 2003-11-23 devnull {
138 056fe1ba 2003-11-23 devnull Frag *f, *ff;
139 056fe1ba 2003-11-23 devnull
140 8baa0cbd 2004-06-09 devnull //if(1)fprint(2, "packetfree %p from %08lux\n", p, getcallerpc(&p));
141 056fe1ba 2003-11-23 devnull
142 056fe1ba 2003-11-23 devnull if(p == nil)
143 056fe1ba 2003-11-23 devnull return;
144 056fe1ba 2003-11-23 devnull
145 056fe1ba 2003-11-23 devnull NOTFREE(p);
146 8baa0cbd 2004-06-09 devnull p->pc = getcallerpc(&p);
147 056fe1ba 2003-11-23 devnull
148 056fe1ba 2003-11-23 devnull for(f=p->first; f!=nil; f=ff) {
149 056fe1ba 2003-11-23 devnull ff = f->next;
150 056fe1ba 2003-11-23 devnull fragfree(f);
151 056fe1ba 2003-11-23 devnull }
152 8baa0cbd 2004-06-09 devnull p->first = (void*)0xDeadBeef;
153 8baa0cbd 2004-06-09 devnull p->last = (void*)0xDeadBeef;
154 8baa0cbd 2004-06-09 devnull p->size = -1;
155 056fe1ba 2003-11-23 devnull
156 056fe1ba 2003-11-23 devnull lock(&freelist.lk);
157 056fe1ba 2003-11-23 devnull p->next = freelist.packet;
158 056fe1ba 2003-11-23 devnull freelist.packet = p;
159 056fe1ba 2003-11-23 devnull unlock(&freelist.lk);
160 056fe1ba 2003-11-23 devnull }
161 056fe1ba 2003-11-23 devnull
162 056fe1ba 2003-11-23 devnull Packet *
163 056fe1ba 2003-11-23 devnull packetdup(Packet *p, int offset, int n)
164 056fe1ba 2003-11-23 devnull {
165 056fe1ba 2003-11-23 devnull Frag *f, *ff;
166 056fe1ba 2003-11-23 devnull Packet *pp;
167 056fe1ba 2003-11-23 devnull
168 056fe1ba 2003-11-23 devnull NOTFREE(p);
169 056fe1ba 2003-11-23 devnull if(offset < 0 || n < 0 || offset+n > p->size) {
170 056fe1ba 2003-11-23 devnull werrstr(EBadSize);
171 056fe1ba 2003-11-23 devnull return nil;
172 056fe1ba 2003-11-23 devnull }
173 056fe1ba 2003-11-23 devnull
174 056fe1ba 2003-11-23 devnull pp = packetalloc();
175 8baa0cbd 2004-06-09 devnull pp->pc = getcallerpc(&p);
176 8baa0cbd 2004-06-09 devnull if(n == 0){
177 8baa0cbd 2004-06-09 devnull NOTFREE(pp);
178 056fe1ba 2003-11-23 devnull return pp;
179 8baa0cbd 2004-06-09 devnull }
180 056fe1ba 2003-11-23 devnull
181 056fe1ba 2003-11-23 devnull pp->size = n;
182 056fe1ba 2003-11-23 devnull
183 056fe1ba 2003-11-23 devnull /* skip offset */
184 056fe1ba 2003-11-23 devnull for(f=p->first; offset >= FRAGSIZE(f); f=f->next)
185 056fe1ba 2003-11-23 devnull offset -= FRAGSIZE(f);
186 056fe1ba 2003-11-23 devnull
187 056fe1ba 2003-11-23 devnull /* first frag */
188 056fe1ba 2003-11-23 devnull ff = fragdup(pp, f);
189 056fe1ba 2003-11-23 devnull ff->rp += offset;
190 056fe1ba 2003-11-23 devnull pp->first = ff;
191 056fe1ba 2003-11-23 devnull n -= FRAGSIZE(ff);
192 056fe1ba 2003-11-23 devnull pp->asize += FRAGASIZE(ff);
193 056fe1ba 2003-11-23 devnull
194 056fe1ba 2003-11-23 devnull /* the remaining */
195 056fe1ba 2003-11-23 devnull while(n > 0) {
196 056fe1ba 2003-11-23 devnull f = f->next;
197 056fe1ba 2003-11-23 devnull ff->next = fragdup(pp, f);
198 056fe1ba 2003-11-23 devnull ff = ff->next;
199 056fe1ba 2003-11-23 devnull n -= FRAGSIZE(ff);
200 056fe1ba 2003-11-23 devnull pp->asize += FRAGASIZE(ff);
201 056fe1ba 2003-11-23 devnull }
202 056fe1ba 2003-11-23 devnull
203 056fe1ba 2003-11-23 devnull /* fix up last frag: note n <= 0 */
204 056fe1ba 2003-11-23 devnull ff->wp += n;
205 056fe1ba 2003-11-23 devnull ff->next = nil;
206 056fe1ba 2003-11-23 devnull pp->last = ff;
207 056fe1ba 2003-11-23 devnull
208 8baa0cbd 2004-06-09 devnull NOTFREE(pp);
209 8baa0cbd 2004-06-09 devnull NOTFREE(p);
210 056fe1ba 2003-11-23 devnull return pp;
211 056fe1ba 2003-11-23 devnull }
212 056fe1ba 2003-11-23 devnull
213 056fe1ba 2003-11-23 devnull Packet *
214 056fe1ba 2003-11-23 devnull packetsplit(Packet *p, int n)
215 056fe1ba 2003-11-23 devnull {
216 056fe1ba 2003-11-23 devnull Packet *pp;
217 056fe1ba 2003-11-23 devnull Frag *f, *ff;
218 056fe1ba 2003-11-23 devnull
219 a09e80f9 2004-05-23 devnull if(0) fprint(2, "packetsplit %p %d\n", p, n);
220 056fe1ba 2003-11-23 devnull NOTFREE(p);
221 056fe1ba 2003-11-23 devnull if(n < 0 || n > p->size) {
222 056fe1ba 2003-11-23 devnull werrstr(EPacketSize);
223 056fe1ba 2003-11-23 devnull return nil;
224 056fe1ba 2003-11-23 devnull }
225 056fe1ba 2003-11-23 devnull
226 056fe1ba 2003-11-23 devnull pp = packetalloc();
227 8baa0cbd 2004-06-09 devnull pp->pc = getcallerpc(&p);
228 8baa0cbd 2004-06-09 devnull if(n == 0){
229 8baa0cbd 2004-06-09 devnull NOTFREE(pp);
230 056fe1ba 2003-11-23 devnull return pp;
231 8baa0cbd 2004-06-09 devnull }
232 056fe1ba 2003-11-23 devnull
233 056fe1ba 2003-11-23 devnull pp->size = n;
234 056fe1ba 2003-11-23 devnull p->size -= n;
235 056fe1ba 2003-11-23 devnull ff = nil;
236 056fe1ba 2003-11-23 devnull for(f=p->first; n > 0 && n >= FRAGSIZE(f); f=f->next) {
237 056fe1ba 2003-11-23 devnull n -= FRAGSIZE(f);
238 056fe1ba 2003-11-23 devnull p->asize -= FRAGASIZE(f);
239 056fe1ba 2003-11-23 devnull pp->asize += FRAGASIZE(f);
240 8baa0cbd 2004-06-09 devnull f->p = pp;
241 056fe1ba 2003-11-23 devnull ff = f;
242 056fe1ba 2003-11-23 devnull }
243 056fe1ba 2003-11-23 devnull
244 056fe1ba 2003-11-23 devnull /* split shared frag */
245 056fe1ba 2003-11-23 devnull if(n > 0) {
246 8baa0cbd 2004-06-09 devnull f->p = pp;
247 056fe1ba 2003-11-23 devnull ff = f;
248 8baa0cbd 2004-06-09 devnull f = fragdup(p, ff);
249 056fe1ba 2003-11-23 devnull pp->asize += FRAGASIZE(ff);
250 056fe1ba 2003-11-23 devnull ff->wp = ff->rp + n;
251 056fe1ba 2003-11-23 devnull f->rp += n;
252 056fe1ba 2003-11-23 devnull }
253 056fe1ba 2003-11-23 devnull
254 056fe1ba 2003-11-23 devnull pp->first = p->first;
255 056fe1ba 2003-11-23 devnull pp->last = ff;
256 8baa0cbd 2004-06-09 devnull ff->next = nil;
257 056fe1ba 2003-11-23 devnull p->first = f;
258 8baa0cbd 2004-06-09 devnull if(f == nil || f->next == nil)
259 8baa0cbd 2004-06-09 devnull p->last = f;
260 8baa0cbd 2004-06-09 devnull NOTFREE(pp);
261 8baa0cbd 2004-06-09 devnull NOTFREE(p);
262 056fe1ba 2003-11-23 devnull return pp;
263 056fe1ba 2003-11-23 devnull }
264 056fe1ba 2003-11-23 devnull
265 056fe1ba 2003-11-23 devnull int
266 056fe1ba 2003-11-23 devnull packetconsume(Packet *p, uchar *buf, int n)
267 056fe1ba 2003-11-23 devnull {
268 a09e80f9 2004-05-23 devnull if(0) fprint(2, "packetconsume %p %d\n", p, n);
269 056fe1ba 2003-11-23 devnull NOTFREE(p);
270 056fe1ba 2003-11-23 devnull if(buf && packetcopy(p, buf, 0, n) < 0)
271 d23a617a 2004-03-15 devnull return -1;
272 056fe1ba 2003-11-23 devnull return packettrim(p, n, p->size-n);
273 056fe1ba 2003-11-23 devnull }
274 056fe1ba 2003-11-23 devnull
275 056fe1ba 2003-11-23 devnull int
276 056fe1ba 2003-11-23 devnull packettrim(Packet *p, int offset, int n)
277 056fe1ba 2003-11-23 devnull {
278 056fe1ba 2003-11-23 devnull Frag *f, *ff;
279 056fe1ba 2003-11-23 devnull
280 a09e80f9 2004-05-23 devnull if(0) fprint(2, "packettrim %p %d %d\n", p, offset, n);
281 056fe1ba 2003-11-23 devnull NOTFREE(p);
282 056fe1ba 2003-11-23 devnull if(offset < 0 || offset > p->size) {
283 056fe1ba 2003-11-23 devnull werrstr(EPacketOffset);
284 056fe1ba 2003-11-23 devnull return -1;
285 056fe1ba 2003-11-23 devnull }
286 056fe1ba 2003-11-23 devnull
287 056fe1ba 2003-11-23 devnull if(n < 0 || offset + n > p->size) {
288 056fe1ba 2003-11-23 devnull werrstr(EPacketOffset);
289 056fe1ba 2003-11-23 devnull return -1;
290 056fe1ba 2003-11-23 devnull }
291 056fe1ba 2003-11-23 devnull
292 056fe1ba 2003-11-23 devnull p->size = n;
293 056fe1ba 2003-11-23 devnull
294 056fe1ba 2003-11-23 devnull /* easy case */
295 056fe1ba 2003-11-23 devnull if(n == 0) {
296 056fe1ba 2003-11-23 devnull for(f=p->first; f != nil; f=ff) {
297 056fe1ba 2003-11-23 devnull ff = f->next;
298 056fe1ba 2003-11-23 devnull fragfree(f);
299 056fe1ba 2003-11-23 devnull }
300 056fe1ba 2003-11-23 devnull p->first = p->last = nil;
301 056fe1ba 2003-11-23 devnull p->asize = 0;
302 8baa0cbd 2004-06-09 devnull NOTFREE(p);
303 056fe1ba 2003-11-23 devnull return 0;
304 056fe1ba 2003-11-23 devnull }
305 056fe1ba 2003-11-23 devnull
306 056fe1ba 2003-11-23 devnull /* free before offset */
307 056fe1ba 2003-11-23 devnull for(f=p->first; offset >= FRAGSIZE(f); f=ff) {
308 056fe1ba 2003-11-23 devnull p->asize -= FRAGASIZE(f);
309 056fe1ba 2003-11-23 devnull offset -= FRAGSIZE(f);
310 056fe1ba 2003-11-23 devnull ff = f->next;
311 056fe1ba 2003-11-23 devnull fragfree(f);
312 056fe1ba 2003-11-23 devnull }
313 056fe1ba 2003-11-23 devnull
314 056fe1ba 2003-11-23 devnull /* adjust frag */
315 056fe1ba 2003-11-23 devnull f->rp += offset;
316 056fe1ba 2003-11-23 devnull p->first = f;
317 056fe1ba 2003-11-23 devnull
318 056fe1ba 2003-11-23 devnull /* skip middle */
319 056fe1ba 2003-11-23 devnull for(; n > 0 && n > FRAGSIZE(f); f=f->next)
320 056fe1ba 2003-11-23 devnull n -= FRAGSIZE(f);
321 056fe1ba 2003-11-23 devnull
322 056fe1ba 2003-11-23 devnull /* adjust end */
323 056fe1ba 2003-11-23 devnull f->wp = f->rp + n;
324 056fe1ba 2003-11-23 devnull p->last = f;
325 056fe1ba 2003-11-23 devnull ff = f->next;
326 056fe1ba 2003-11-23 devnull f->next = nil;
327 056fe1ba 2003-11-23 devnull
328 056fe1ba 2003-11-23 devnull /* free after */
329 056fe1ba 2003-11-23 devnull for(f=ff; f != nil; f=ff) {
330 056fe1ba 2003-11-23 devnull p->asize -= FRAGASIZE(f);
331 056fe1ba 2003-11-23 devnull ff = f->next;
332 056fe1ba 2003-11-23 devnull fragfree(f);
333 056fe1ba 2003-11-23 devnull }
334 8baa0cbd 2004-06-09 devnull NOTFREE(p);
335 056fe1ba 2003-11-23 devnull return 0;
336 056fe1ba 2003-11-23 devnull }
337 056fe1ba 2003-11-23 devnull
338 056fe1ba 2003-11-23 devnull uchar *
339 056fe1ba 2003-11-23 devnull packetheader(Packet *p, int n)
340 056fe1ba 2003-11-23 devnull {
341 056fe1ba 2003-11-23 devnull Frag *f;
342 056fe1ba 2003-11-23 devnull Mem *m;
343 056fe1ba 2003-11-23 devnull
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;
348 056fe1ba 2003-11-23 devnull }
349 056fe1ba 2003-11-23 devnull
350 056fe1ba 2003-11-23 devnull p->size += n;
351 056fe1ba 2003-11-23 devnull
352 056fe1ba 2003-11-23 devnull /* try and fix in current frag */
353 056fe1ba 2003-11-23 devnull f = p->first;
354 056fe1ba 2003-11-23 devnull if(f != nil) {
355 056fe1ba 2003-11-23 devnull m = f->mem;
356 056fe1ba 2003-11-23 devnull if(n <= f->rp - m->bp)
357 056fe1ba 2003-11-23 devnull if(m->ref == 1 || memhead(m, f->rp, n) >= 0) {
358 056fe1ba 2003-11-23 devnull f->rp -= n;
359 8baa0cbd 2004-06-09 devnull NOTFREE(p);
360 056fe1ba 2003-11-23 devnull return f->rp;
361 056fe1ba 2003-11-23 devnull }
362 056fe1ba 2003-11-23 devnull }
363 056fe1ba 2003-11-23 devnull
364 056fe1ba 2003-11-23 devnull /* add frag to front */
365 056fe1ba 2003-11-23 devnull f = fragalloc(p, n, PEnd, p->first);
366 056fe1ba 2003-11-23 devnull p->asize += FRAGASIZE(f);
367 056fe1ba 2003-11-23 devnull if(p->first == nil)
368 056fe1ba 2003-11-23 devnull p->last = f;
369 056fe1ba 2003-11-23 devnull p->first = f;
370 8baa0cbd 2004-06-09 devnull NOTFREE(p);
371 056fe1ba 2003-11-23 devnull return f->rp;
372 056fe1ba 2003-11-23 devnull }
373 056fe1ba 2003-11-23 devnull
374 056fe1ba 2003-11-23 devnull uchar *
375 056fe1ba 2003-11-23 devnull packettrailer(Packet *p, int n)
376 056fe1ba 2003-11-23 devnull {
377 056fe1ba 2003-11-23 devnull Mem *m;
378 056fe1ba 2003-11-23 devnull Frag *f;
379 056fe1ba 2003-11-23 devnull
380 a09e80f9 2004-05-23 devnull if(0) fprint(2, "packettrailer %p %d\n", p, n);
381 056fe1ba 2003-11-23 devnull NOTFREE(p);
382 056fe1ba 2003-11-23 devnull if(n <= 0 || n > MaxFragSize) {
383 056fe1ba 2003-11-23 devnull werrstr(EPacketSize);
384 056fe1ba 2003-11-23 devnull return nil;
385 056fe1ba 2003-11-23 devnull }
386 056fe1ba 2003-11-23 devnull
387 056fe1ba 2003-11-23 devnull p->size += n;
388 056fe1ba 2003-11-23 devnull
389 056fe1ba 2003-11-23 devnull /* try and fix in current frag */
390 056fe1ba 2003-11-23 devnull if(p->first != nil) {
391 056fe1ba 2003-11-23 devnull f = p->last;
392 056fe1ba 2003-11-23 devnull m = f->mem;
393 056fe1ba 2003-11-23 devnull if(n <= m->ep - f->wp)
394 056fe1ba 2003-11-23 devnull if(m->ref == 1 || memtail(m, f->wp, n) >= 0) {
395 056fe1ba 2003-11-23 devnull f->wp += n;
396 8baa0cbd 2004-06-09 devnull NOTFREE(p);
397 056fe1ba 2003-11-23 devnull return f->wp - n;
398 056fe1ba 2003-11-23 devnull }
399 056fe1ba 2003-11-23 devnull }
400 056fe1ba 2003-11-23 devnull
401 056fe1ba 2003-11-23 devnull /* add frag to end */
402 056fe1ba 2003-11-23 devnull f = fragalloc(p, n, (p->first == nil)?PMiddle:PFront, nil);
403 056fe1ba 2003-11-23 devnull p->asize += FRAGASIZE(f);
404 056fe1ba 2003-11-23 devnull if(p->first == nil)
405 056fe1ba 2003-11-23 devnull p->first = f;
406 056fe1ba 2003-11-23 devnull else
407 056fe1ba 2003-11-23 devnull p->last->next = f;
408 056fe1ba 2003-11-23 devnull p->last = f;
409 8baa0cbd 2004-06-09 devnull NOTFREE(p);
410 056fe1ba 2003-11-23 devnull return f->rp;
411 056fe1ba 2003-11-23 devnull }
412 056fe1ba 2003-11-23 devnull
413 d23a617a 2004-03-15 devnull void
414 056fe1ba 2003-11-23 devnull packetprefix(Packet *p, uchar *buf, int n)
415 056fe1ba 2003-11-23 devnull {
416 056fe1ba 2003-11-23 devnull Frag *f;
417 056fe1ba 2003-11-23 devnull int nn;
418 056fe1ba 2003-11-23 devnull Mem *m;
419 056fe1ba 2003-11-23 devnull
420 056fe1ba 2003-11-23 devnull NOTFREE(p);
421 056fe1ba 2003-11-23 devnull if(n <= 0)
422 d23a617a 2004-03-15 devnull return;
423 056fe1ba 2003-11-23 devnull
424 056fe1ba 2003-11-23 devnull p->size += n;
425 056fe1ba 2003-11-23 devnull
426 056fe1ba 2003-11-23 devnull /* try and fix in current frag */
427 056fe1ba 2003-11-23 devnull f = p->first;
428 056fe1ba 2003-11-23 devnull if(f != nil) {
429 056fe1ba 2003-11-23 devnull m = f->mem;
430 056fe1ba 2003-11-23 devnull nn = f->rp - m->bp;
431 056fe1ba 2003-11-23 devnull if(nn > n)
432 056fe1ba 2003-11-23 devnull nn = n;
433 056fe1ba 2003-11-23 devnull if(m->ref == 1 || memhead(m, f->rp, nn) >= 0) {
434 056fe1ba 2003-11-23 devnull f->rp -= nn;
435 056fe1ba 2003-11-23 devnull n -= nn;
436 056fe1ba 2003-11-23 devnull memmove(f->rp, buf+n, nn);
437 056fe1ba 2003-11-23 devnull }
438 056fe1ba 2003-11-23 devnull }
439 056fe1ba 2003-11-23 devnull
440 056fe1ba 2003-11-23 devnull while(n > 0) {
441 056fe1ba 2003-11-23 devnull nn = n;
442 056fe1ba 2003-11-23 devnull if(nn > MaxFragSize)
443 056fe1ba 2003-11-23 devnull nn = MaxFragSize;
444 056fe1ba 2003-11-23 devnull f = fragalloc(p, nn, PEnd, p->first);
445 056fe1ba 2003-11-23 devnull p->asize += FRAGASIZE(f);
446 056fe1ba 2003-11-23 devnull if(p->first == nil)
447 056fe1ba 2003-11-23 devnull p->last = f;
448 056fe1ba 2003-11-23 devnull p->first = f;
449 056fe1ba 2003-11-23 devnull n -= nn;
450 056fe1ba 2003-11-23 devnull memmove(f->rp, buf+n, nn);
451 056fe1ba 2003-11-23 devnull }
452 8baa0cbd 2004-06-09 devnull NOTFREE(p);
453 056fe1ba 2003-11-23 devnull }
454 056fe1ba 2003-11-23 devnull
455 d23a617a 2004-03-15 devnull void
456 056fe1ba 2003-11-23 devnull packetappend(Packet *p, uchar *buf, int n)
457 056fe1ba 2003-11-23 devnull {
458 056fe1ba 2003-11-23 devnull Frag *f;
459 056fe1ba 2003-11-23 devnull int nn;
460 056fe1ba 2003-11-23 devnull Mem *m;
461 056fe1ba 2003-11-23 devnull
462 056fe1ba 2003-11-23 devnull NOTFREE(p);
463 056fe1ba 2003-11-23 devnull if(n <= 0)
464 d23a617a 2004-03-15 devnull return;
465 056fe1ba 2003-11-23 devnull
466 056fe1ba 2003-11-23 devnull p->size += n;
467 056fe1ba 2003-11-23 devnull /* try and fix in current frag */
468 056fe1ba 2003-11-23 devnull if(p->first != nil) {
469 056fe1ba 2003-11-23 devnull f = p->last;
470 056fe1ba 2003-11-23 devnull m = f->mem;
471 056fe1ba 2003-11-23 devnull nn = m->ep - f->wp;
472 056fe1ba 2003-11-23 devnull if(nn > n)
473 056fe1ba 2003-11-23 devnull nn = n;
474 056fe1ba 2003-11-23 devnull if(m->ref == 1 || memtail(m, f->wp, nn) >= 0) {
475 056fe1ba 2003-11-23 devnull memmove(f->wp, buf, nn);
476 056fe1ba 2003-11-23 devnull f->wp += nn;
477 056fe1ba 2003-11-23 devnull buf += nn;
478 056fe1ba 2003-11-23 devnull n -= nn;
479 056fe1ba 2003-11-23 devnull }
480 056fe1ba 2003-11-23 devnull }
481 056fe1ba 2003-11-23 devnull
482 056fe1ba 2003-11-23 devnull while(n > 0) {
483 056fe1ba 2003-11-23 devnull nn = n;
484 056fe1ba 2003-11-23 devnull if(nn > MaxFragSize)
485 056fe1ba 2003-11-23 devnull nn = MaxFragSize;
486 056fe1ba 2003-11-23 devnull f = fragalloc(p, nn, (p->first == nil)?PMiddle:PFront, nil);
487 056fe1ba 2003-11-23 devnull p->asize += FRAGASIZE(f);
488 056fe1ba 2003-11-23 devnull if(p->first == nil)
489 056fe1ba 2003-11-23 devnull p->first = f;
490 056fe1ba 2003-11-23 devnull else
491 056fe1ba 2003-11-23 devnull p->last->next = f;
492 056fe1ba 2003-11-23 devnull p->last = f;
493 056fe1ba 2003-11-23 devnull memmove(f->rp, buf, nn);
494 056fe1ba 2003-11-23 devnull buf += nn;
495 056fe1ba 2003-11-23 devnull n -= nn;
496 056fe1ba 2003-11-23 devnull }
497 8baa0cbd 2004-06-09 devnull NOTFREE(p);
498 056fe1ba 2003-11-23 devnull }
499 056fe1ba 2003-11-23 devnull
500 d23a617a 2004-03-15 devnull void
501 056fe1ba 2003-11-23 devnull packetconcat(Packet *p, Packet *pp)
502 056fe1ba 2003-11-23 devnull {
503 8baa0cbd 2004-06-09 devnull Frag *f;
504 8baa0cbd 2004-06-09 devnull
505 056fe1ba 2003-11-23 devnull NOTFREE(p);
506 056fe1ba 2003-11-23 devnull NOTFREE(pp);
507 056fe1ba 2003-11-23 devnull if(pp->size == 0)
508 d23a617a 2004-03-15 devnull return;
509 056fe1ba 2003-11-23 devnull p->size += pp->size;
510 056fe1ba 2003-11-23 devnull p->asize += pp->asize;
511 8baa0cbd 2004-06-09 devnull for(f=pp->first; f; f=f->next)
512 8baa0cbd 2004-06-09 devnull f->p = p;
513 056fe1ba 2003-11-23 devnull
514 056fe1ba 2003-11-23 devnull if(p->first != nil)
515 056fe1ba 2003-11-23 devnull p->last->next = pp->first;
516 056fe1ba 2003-11-23 devnull else
517 056fe1ba 2003-11-23 devnull p->first = pp->first;
518 8baa0cbd 2004-06-09 devnull
519 056fe1ba 2003-11-23 devnull p->last = pp->last;
520 056fe1ba 2003-11-23 devnull pp->size = 0;
521 056fe1ba 2003-11-23 devnull pp->asize = 0;
522 056fe1ba 2003-11-23 devnull pp->first = nil;
523 056fe1ba 2003-11-23 devnull pp->last = nil;
524 8baa0cbd 2004-06-09 devnull NOTFREE(p);
525 8baa0cbd 2004-06-09 devnull NOTFREE(pp);
526 056fe1ba 2003-11-23 devnull }
527 056fe1ba 2003-11-23 devnull
528 056fe1ba 2003-11-23 devnull uchar *
529 056fe1ba 2003-11-23 devnull packetpeek(Packet *p, uchar *buf, int offset, int n)
530 056fe1ba 2003-11-23 devnull {
531 056fe1ba 2003-11-23 devnull Frag *f;
532 056fe1ba 2003-11-23 devnull int nn;
533 056fe1ba 2003-11-23 devnull uchar *b;
534 056fe1ba 2003-11-23 devnull
535 056fe1ba 2003-11-23 devnull NOTFREE(p);
536 056fe1ba 2003-11-23 devnull if(n == 0)
537 056fe1ba 2003-11-23 devnull return buf;
538 056fe1ba 2003-11-23 devnull
539 056fe1ba 2003-11-23 devnull if(offset < 0 || offset >= p->size) {
540 056fe1ba 2003-11-23 devnull werrstr(EPacketOffset);
541 056fe1ba 2003-11-23 devnull return nil;
542 056fe1ba 2003-11-23 devnull }
543 056fe1ba 2003-11-23 devnull
544 056fe1ba 2003-11-23 devnull if(n < 0 || offset + n > p->size) {
545 056fe1ba 2003-11-23 devnull werrstr(EPacketSize);
546 056fe1ba 2003-11-23 devnull return nil;
547 056fe1ba 2003-11-23 devnull }
548 056fe1ba 2003-11-23 devnull
549 056fe1ba 2003-11-23 devnull /* skip up to offset */
550 056fe1ba 2003-11-23 devnull for(f=p->first; offset >= FRAGSIZE(f); f=f->next)
551 056fe1ba 2003-11-23 devnull offset -= FRAGSIZE(f);
552 056fe1ba 2003-11-23 devnull
553 056fe1ba 2003-11-23 devnull /* easy case */
554 8baa0cbd 2004-06-09 devnull if(offset + n <= FRAGSIZE(f)){
555 8baa0cbd 2004-06-09 devnull NOTFREE(p);
556 056fe1ba 2003-11-23 devnull return f->rp + offset;
557 8baa0cbd 2004-06-09 devnull }
558 056fe1ba 2003-11-23 devnull
559 056fe1ba 2003-11-23 devnull for(b=buf; n>0; n -= nn) {
560 056fe1ba 2003-11-23 devnull nn = FRAGSIZE(f) - offset;
561 056fe1ba 2003-11-23 devnull if(nn > n)
562 056fe1ba 2003-11-23 devnull nn = n;
563 056fe1ba 2003-11-23 devnull memmove(b, f->rp+offset, nn);
564 056fe1ba 2003-11-23 devnull offset = 0;
565 056fe1ba 2003-11-23 devnull f = f->next;
566 056fe1ba 2003-11-23 devnull b += nn;
567 056fe1ba 2003-11-23 devnull }
568 056fe1ba 2003-11-23 devnull
569 8baa0cbd 2004-06-09 devnull NOTFREE(p);
570 056fe1ba 2003-11-23 devnull return buf;
571 056fe1ba 2003-11-23 devnull }
572 056fe1ba 2003-11-23 devnull
573 056fe1ba 2003-11-23 devnull int
574 056fe1ba 2003-11-23 devnull packetcopy(Packet *p, uchar *buf, int offset, int n)
575 056fe1ba 2003-11-23 devnull {
576 056fe1ba 2003-11-23 devnull uchar *b;
577 056fe1ba 2003-11-23 devnull
578 056fe1ba 2003-11-23 devnull NOTFREE(p);
579 056fe1ba 2003-11-23 devnull b = packetpeek(p, buf, offset, n);
580 056fe1ba 2003-11-23 devnull if(b == nil)
581 056fe1ba 2003-11-23 devnull return -1;
582 056fe1ba 2003-11-23 devnull if(b != buf)
583 056fe1ba 2003-11-23 devnull memmove(buf, b, n);
584 056fe1ba 2003-11-23 devnull return 0;
585 056fe1ba 2003-11-23 devnull }
586 056fe1ba 2003-11-23 devnull
587 056fe1ba 2003-11-23 devnull int
588 056fe1ba 2003-11-23 devnull packetfragments(Packet *p, IOchunk *io, int nio, int offset)
589 056fe1ba 2003-11-23 devnull {
590 056fe1ba 2003-11-23 devnull Frag *f;
591 056fe1ba 2003-11-23 devnull int size;
592 056fe1ba 2003-11-23 devnull IOchunk *eio;
593 056fe1ba 2003-11-23 devnull
594 056fe1ba 2003-11-23 devnull NOTFREE(p);
595 056fe1ba 2003-11-23 devnull if(p->size == 0 || nio <= 0)
596 056fe1ba 2003-11-23 devnull return 0;
597 056fe1ba 2003-11-23 devnull
598 056fe1ba 2003-11-23 devnull if(offset < 0 || offset > p->size) {
599 056fe1ba 2003-11-23 devnull werrstr(EPacketOffset);
600 056fe1ba 2003-11-23 devnull return -1;
601 056fe1ba 2003-11-23 devnull }
602 056fe1ba 2003-11-23 devnull
603 056fe1ba 2003-11-23 devnull for(f=p->first; offset >= FRAGSIZE(f); f=f->next)
604 056fe1ba 2003-11-23 devnull offset -= FRAGSIZE(f);
605 056fe1ba 2003-11-23 devnull
606 056fe1ba 2003-11-23 devnull size = 0;
607 056fe1ba 2003-11-23 devnull eio = io + nio;
608 056fe1ba 2003-11-23 devnull for(; f != nil && io < eio; f=f->next) {
609 056fe1ba 2003-11-23 devnull io->addr = f->rp + offset;
610 056fe1ba 2003-11-23 devnull io->len = f->wp - (f->rp + offset);
611 056fe1ba 2003-11-23 devnull offset = 0;
612 056fe1ba 2003-11-23 devnull size += io->len;
613 056fe1ba 2003-11-23 devnull io++;
614 056fe1ba 2003-11-23 devnull }
615 9c8fc128 2005-07-13 devnull for(; io < eio; io++){
616 9c8fc128 2005-07-13 devnull io->addr = nil;
617 9c8fc128 2005-07-13 devnull io->len = 0;
618 9c8fc128 2005-07-13 devnull }
619 056fe1ba 2003-11-23 devnull return size;
620 056fe1ba 2003-11-23 devnull }
621 056fe1ba 2003-11-23 devnull
622 056fe1ba 2003-11-23 devnull void
623 056fe1ba 2003-11-23 devnull packetstats(void)
624 056fe1ba 2003-11-23 devnull {
625 056fe1ba 2003-11-23 devnull Packet *p;
626 056fe1ba 2003-11-23 devnull Frag *f;
627 056fe1ba 2003-11-23 devnull Mem *m;
628 056fe1ba 2003-11-23 devnull
629 056fe1ba 2003-11-23 devnull int np, nf, nsm, nbm;
630 056fe1ba 2003-11-23 devnull
631 056fe1ba 2003-11-23 devnull lock(&freelist.lk);
632 056fe1ba 2003-11-23 devnull np = 0;
633 056fe1ba 2003-11-23 devnull for(p=freelist.packet; p; p=p->next)
634 056fe1ba 2003-11-23 devnull np++;
635 056fe1ba 2003-11-23 devnull nf = 0;
636 056fe1ba 2003-11-23 devnull for(f=freelist.frag; f; f=f->next)
637 056fe1ba 2003-11-23 devnull nf++;
638 056fe1ba 2003-11-23 devnull nsm = 0;
639 056fe1ba 2003-11-23 devnull for(m=freelist.smallmem; m; m=m->next)
640 056fe1ba 2003-11-23 devnull nsm++;
641 056fe1ba 2003-11-23 devnull nbm = 0;
642 056fe1ba 2003-11-23 devnull for(m=freelist.bigmem; m; m=m->next)
643 056fe1ba 2003-11-23 devnull nbm++;
644 056fe1ba 2003-11-23 devnull
645 056fe1ba 2003-11-23 devnull fprint(2, "packet: %d/%d frag: %d/%d small mem: %d/%d big mem: %d/%d\n",
646 056fe1ba 2003-11-23 devnull np, freelist.npacket,
647 056fe1ba 2003-11-23 devnull nf, freelist.nfrag,
648 056fe1ba 2003-11-23 devnull nsm, freelist.nsmallmem,
649 056fe1ba 2003-11-23 devnull nbm, freelist.nbigmem);
650 056fe1ba 2003-11-23 devnull
651 056fe1ba 2003-11-23 devnull unlock(&freelist.lk);
652 056fe1ba 2003-11-23 devnull }
653 056fe1ba 2003-11-23 devnull
654 056fe1ba 2003-11-23 devnull
655 056fe1ba 2003-11-23 devnull uint
656 056fe1ba 2003-11-23 devnull packetsize(Packet *p)
657 056fe1ba 2003-11-23 devnull {
658 056fe1ba 2003-11-23 devnull NOTFREE(p);
659 a09e80f9 2004-05-23 devnull if(1) {
660 056fe1ba 2003-11-23 devnull Frag *f;
661 056fe1ba 2003-11-23 devnull int size = 0;
662 056fe1ba 2003-11-23 devnull
663 056fe1ba 2003-11-23 devnull for(f=p->first; f; f=f->next)
664 056fe1ba 2003-11-23 devnull size += FRAGSIZE(f);
665 056fe1ba 2003-11-23 devnull if(size != p->size)
666 056fe1ba 2003-11-23 devnull fprint(2, "packetsize %d %d\n", size, p->size);
667 056fe1ba 2003-11-23 devnull assert(size == p->size);
668 056fe1ba 2003-11-23 devnull }
669 056fe1ba 2003-11-23 devnull return p->size;
670 056fe1ba 2003-11-23 devnull }
671 056fe1ba 2003-11-23 devnull
672 056fe1ba 2003-11-23 devnull uint
673 056fe1ba 2003-11-23 devnull packetasize(Packet *p)
674 056fe1ba 2003-11-23 devnull {
675 056fe1ba 2003-11-23 devnull NOTFREE(p);
676 056fe1ba 2003-11-23 devnull if(0) {
677 056fe1ba 2003-11-23 devnull Frag *f;
678 056fe1ba 2003-11-23 devnull int asize = 0;
679 056fe1ba 2003-11-23 devnull
680 056fe1ba 2003-11-23 devnull for(f=p->first; f; f=f->next)
681 056fe1ba 2003-11-23 devnull asize += FRAGASIZE(f);
682 056fe1ba 2003-11-23 devnull if(asize != p->asize)
683 056fe1ba 2003-11-23 devnull fprint(2, "packetasize %d %d\n", asize, p->asize);
684 056fe1ba 2003-11-23 devnull assert(asize == p->asize);
685 056fe1ba 2003-11-23 devnull }
686 056fe1ba 2003-11-23 devnull return p->asize;
687 056fe1ba 2003-11-23 devnull }
688 056fe1ba 2003-11-23 devnull
689 056fe1ba 2003-11-23 devnull void
690 056fe1ba 2003-11-23 devnull packetsha1(Packet *p, uchar digest[VtScoreSize])
691 056fe1ba 2003-11-23 devnull {
692 056fe1ba 2003-11-23 devnull DigestState ds;
693 056fe1ba 2003-11-23 devnull Frag *f;
694 056fe1ba 2003-11-23 devnull int size;
695 056fe1ba 2003-11-23 devnull
696 056fe1ba 2003-11-23 devnull NOTFREE(p);
697 056fe1ba 2003-11-23 devnull memset(&ds, 0, sizeof ds);
698 056fe1ba 2003-11-23 devnull size = p->size;
699 056fe1ba 2003-11-23 devnull for(f=p->first; f; f=f->next) {
700 056fe1ba 2003-11-23 devnull sha1(f->rp, FRAGSIZE(f), nil, &ds);
701 056fe1ba 2003-11-23 devnull size -= FRAGSIZE(f);
702 056fe1ba 2003-11-23 devnull }
703 056fe1ba 2003-11-23 devnull assert(size == 0);
704 056fe1ba 2003-11-23 devnull sha1(nil, 0, digest, &ds);
705 056fe1ba 2003-11-23 devnull }
706 056fe1ba 2003-11-23 devnull
707 056fe1ba 2003-11-23 devnull int
708 056fe1ba 2003-11-23 devnull packetcmp(Packet *pkt0, Packet *pkt1)
709 056fe1ba 2003-11-23 devnull {
710 056fe1ba 2003-11-23 devnull Frag *f0, *f1;
711 056fe1ba 2003-11-23 devnull int n0, n1, x;
712 056fe1ba 2003-11-23 devnull
713 056fe1ba 2003-11-23 devnull NOTFREE(pkt0);
714 056fe1ba 2003-11-23 devnull NOTFREE(pkt1);
715 056fe1ba 2003-11-23 devnull f0 = pkt0->first;
716 056fe1ba 2003-11-23 devnull f1 = pkt1->first;
717 056fe1ba 2003-11-23 devnull
718 056fe1ba 2003-11-23 devnull if(f0 == nil)
719 056fe1ba 2003-11-23 devnull return (f1 == nil)?0:-1;
720 056fe1ba 2003-11-23 devnull if(f1 == nil)
721 056fe1ba 2003-11-23 devnull return 1;
722 056fe1ba 2003-11-23 devnull n0 = FRAGSIZE(f0);
723 056fe1ba 2003-11-23 devnull n1 = FRAGSIZE(f1);
724 056fe1ba 2003-11-23 devnull
725 056fe1ba 2003-11-23 devnull for(;;) {
726 056fe1ba 2003-11-23 devnull if(n0 < n1) {
727 056fe1ba 2003-11-23 devnull x = memcmp(f0->wp - n0, f1->wp - n1, n0);
728 056fe1ba 2003-11-23 devnull if(x != 0)
729 056fe1ba 2003-11-23 devnull return x;
730 056fe1ba 2003-11-23 devnull n1 -= n0;
731 056fe1ba 2003-11-23 devnull f0 = f0->next;
732 056fe1ba 2003-11-23 devnull if(f0 == nil)
733 056fe1ba 2003-11-23 devnull return -1;
734 056fe1ba 2003-11-23 devnull n0 = FRAGSIZE(f0);
735 056fe1ba 2003-11-23 devnull } else if (n0 > n1) {
736 056fe1ba 2003-11-23 devnull x = memcmp(f0->wp - n0, f1->wp - n1, n1);
737 056fe1ba 2003-11-23 devnull if(x != 0)
738 056fe1ba 2003-11-23 devnull return x;
739 056fe1ba 2003-11-23 devnull n0 -= n1;
740 056fe1ba 2003-11-23 devnull f1 = f1->next;
741 056fe1ba 2003-11-23 devnull if(f1 == nil)
742 056fe1ba 2003-11-23 devnull return 1;
743 056fe1ba 2003-11-23 devnull n1 = FRAGSIZE(f1);
744 056fe1ba 2003-11-23 devnull } else { /* n0 == n1 */
745 056fe1ba 2003-11-23 devnull x = memcmp(f0->wp - n0, f1->wp - n1, n0);
746 056fe1ba 2003-11-23 devnull if(x != 0)
747 056fe1ba 2003-11-23 devnull return x;
748 056fe1ba 2003-11-23 devnull f0 = f0->next;
749 056fe1ba 2003-11-23 devnull f1 = f1->next;
750 056fe1ba 2003-11-23 devnull if(f0 == nil)
751 056fe1ba 2003-11-23 devnull return (f1 == nil)?0:-1;
752 056fe1ba 2003-11-23 devnull if(f1 == nil)
753 056fe1ba 2003-11-23 devnull return 1;
754 056fe1ba 2003-11-23 devnull n0 = FRAGSIZE(f0);
755 056fe1ba 2003-11-23 devnull n1 = FRAGSIZE(f1);
756 056fe1ba 2003-11-23 devnull }
757 056fe1ba 2003-11-23 devnull }
758 056fe1ba 2003-11-23 devnull }
759 056fe1ba 2003-11-23 devnull
760 056fe1ba 2003-11-23 devnull
761 056fe1ba 2003-11-23 devnull static Frag *
762 056fe1ba 2003-11-23 devnull fragalloc(Packet *p, int n, int pos, Frag *next)
763 056fe1ba 2003-11-23 devnull {
764 056fe1ba 2003-11-23 devnull Frag *f, *ef;
765 056fe1ba 2003-11-23 devnull Mem *m;
766 056fe1ba 2003-11-23 devnull
767 056fe1ba 2003-11-23 devnull /* look for local frag */
768 056fe1ba 2003-11-23 devnull f = &p->local[0];
769 056fe1ba 2003-11-23 devnull ef = &p->local[NLocalFrag];
770 056fe1ba 2003-11-23 devnull for(;f<ef; f++) {
771 056fe1ba 2003-11-23 devnull if(f->state == FragLocalFree) {
772 056fe1ba 2003-11-23 devnull f->state = FragLocalAlloc;
773 056fe1ba 2003-11-23 devnull goto Found;
774 056fe1ba 2003-11-23 devnull }
775 056fe1ba 2003-11-23 devnull }
776 056fe1ba 2003-11-23 devnull lock(&freelist.lk);
777 056fe1ba 2003-11-23 devnull f = freelist.frag;
778 056fe1ba 2003-11-23 devnull if(f != nil)
779 056fe1ba 2003-11-23 devnull freelist.frag = f->next;
780 056fe1ba 2003-11-23 devnull else
781 056fe1ba 2003-11-23 devnull freelist.nfrag++;
782 056fe1ba 2003-11-23 devnull unlock(&freelist.lk);
783 056fe1ba 2003-11-23 devnull
784 056fe1ba 2003-11-23 devnull if(f == nil) {
785 056fe1ba 2003-11-23 devnull f = vtbrk(sizeof(Frag));
786 056fe1ba 2003-11-23 devnull f->state = FragGlobal;
787 056fe1ba 2003-11-23 devnull }
788 056fe1ba 2003-11-23 devnull
789 056fe1ba 2003-11-23 devnull Found:
790 056fe1ba 2003-11-23 devnull f->next = next;
791 8baa0cbd 2004-06-09 devnull f->p = p;
792 056fe1ba 2003-11-23 devnull
793 056fe1ba 2003-11-23 devnull if(n == 0){
794 056fe1ba 2003-11-23 devnull f->mem = 0;
795 056fe1ba 2003-11-23 devnull f->rp = 0;
796 056fe1ba 2003-11-23 devnull f->wp = 0;
797 056fe1ba 2003-11-23 devnull return f;
798 056fe1ba 2003-11-23 devnull }
799 056fe1ba 2003-11-23 devnull
800 056fe1ba 2003-11-23 devnull if(pos == PEnd && next == nil)
801 056fe1ba 2003-11-23 devnull pos = PMiddle;
802 056fe1ba 2003-11-23 devnull m = memalloc(n, pos);
803 056fe1ba 2003-11-23 devnull f->mem = m;
804 056fe1ba 2003-11-23 devnull f->rp = m->rp;
805 056fe1ba 2003-11-23 devnull f->wp = m->wp;
806 056fe1ba 2003-11-23 devnull return f;
807 056fe1ba 2003-11-23 devnull }
808 056fe1ba 2003-11-23 devnull
809 056fe1ba 2003-11-23 devnull Packet*
810 056fe1ba 2003-11-23 devnull packetforeign(uchar *buf, int n, void (*free)(void *a), void *a)
811 056fe1ba 2003-11-23 devnull {
812 056fe1ba 2003-11-23 devnull Packet *p;
813 056fe1ba 2003-11-23 devnull Frag *f;
814 056fe1ba 2003-11-23 devnull
815 056fe1ba 2003-11-23 devnull p = packetalloc();
816 8baa0cbd 2004-06-09 devnull p->pc = getcallerpc(&buf);
817 056fe1ba 2003-11-23 devnull f = fragalloc(p, 0, 0, nil);
818 056fe1ba 2003-11-23 devnull f->free = free;
819 056fe1ba 2003-11-23 devnull f->a = a;
820 056fe1ba 2003-11-23 devnull f->next = nil;
821 056fe1ba 2003-11-23 devnull f->rp = buf;
822 056fe1ba 2003-11-23 devnull f->wp = buf+n;
823 056fe1ba 2003-11-23 devnull
824 056fe1ba 2003-11-23 devnull p->first = f;
825 8baa0cbd 2004-06-09 devnull p->last = f;
826 056fe1ba 2003-11-23 devnull p->size = n;
827 8baa0cbd 2004-06-09 devnull NOTFREE(p);
828 056fe1ba 2003-11-23 devnull return p;
829 056fe1ba 2003-11-23 devnull }
830 056fe1ba 2003-11-23 devnull
831 056fe1ba 2003-11-23 devnull static Frag *
832 056fe1ba 2003-11-23 devnull fragdup(Packet *p, Frag *f)
833 056fe1ba 2003-11-23 devnull {
834 056fe1ba 2003-11-23 devnull Frag *ff;
835 056fe1ba 2003-11-23 devnull Mem *m;
836 056fe1ba 2003-11-23 devnull
837 056fe1ba 2003-11-23 devnull m = f->mem;
838 056fe1ba 2003-11-23 devnull
839 056fe1ba 2003-11-23 devnull /*
840 056fe1ba 2003-11-23 devnull * m->rp && m->wp can be out of date when ref == 1
841 056fe1ba 2003-11-23 devnull * also, potentially reclaims space from previous frags
842 056fe1ba 2003-11-23 devnull */
843 056fe1ba 2003-11-23 devnull if(m && m->ref == 1) {
844 056fe1ba 2003-11-23 devnull m->rp = f->rp;
845 056fe1ba 2003-11-23 devnull m->wp = f->wp;
846 056fe1ba 2003-11-23 devnull }
847 056fe1ba 2003-11-23 devnull
848 056fe1ba 2003-11-23 devnull ff = fragalloc(p, 0, 0, nil);
849 8baa0cbd 2004-06-09 devnull ff->mem = f->mem;
850 8baa0cbd 2004-06-09 devnull ff->rp = f->rp;
851 8baa0cbd 2004-06-09 devnull ff->wp = f->wp;
852 8baa0cbd 2004-06-09 devnull ff->next = f->next;
853 8baa0cbd 2004-06-09 devnull
854 8baa0cbd 2004-06-09 devnull /*
855 8baa0cbd 2004-06-09 devnull * We can't duplicate these -- there's no dup function.
856 8baa0cbd 2004-06-09 devnull */
857 8baa0cbd 2004-06-09 devnull assert(f->free==nil && f->a==nil);
858 8baa0cbd 2004-06-09 devnull
859 056fe1ba 2003-11-23 devnull if(m){
860 056fe1ba 2003-11-23 devnull lock(&m->lk);
861 056fe1ba 2003-11-23 devnull m->ref++;
862 056fe1ba 2003-11-23 devnull unlock(&m->lk);
863 056fe1ba 2003-11-23 devnull }
864 8baa0cbd 2004-06-09 devnull
865 8baa0cbd 2004-06-09 devnull
866 056fe1ba 2003-11-23 devnull return ff;
867 056fe1ba 2003-11-23 devnull }
868 056fe1ba 2003-11-23 devnull
869 056fe1ba 2003-11-23 devnull
870 056fe1ba 2003-11-23 devnull static void
871 056fe1ba 2003-11-23 devnull fragfree(Frag *f)
872 056fe1ba 2003-11-23 devnull {
873 056fe1ba 2003-11-23 devnull if(f->mem == nil){
874 056fe1ba 2003-11-23 devnull if(f->free)
875 056fe1ba 2003-11-23 devnull (*f->free)(f->a);
876 056fe1ba 2003-11-23 devnull }else{
877 056fe1ba 2003-11-23 devnull memfree(f->mem);
878 056fe1ba 2003-11-23 devnull f->mem = 0;
879 056fe1ba 2003-11-23 devnull }
880 056fe1ba 2003-11-23 devnull
881 056fe1ba 2003-11-23 devnull if(f->state == FragLocalAlloc) {
882 056fe1ba 2003-11-23 devnull f->state = FragLocalFree;
883 056fe1ba 2003-11-23 devnull return;
884 056fe1ba 2003-11-23 devnull }
885 056fe1ba 2003-11-23 devnull
886 056fe1ba 2003-11-23 devnull lock(&freelist.lk);
887 056fe1ba 2003-11-23 devnull f->next = freelist.frag;
888 056fe1ba 2003-11-23 devnull freelist.frag = f;
889 056fe1ba 2003-11-23 devnull unlock(&freelist.lk);
890 056fe1ba 2003-11-23 devnull }
891 056fe1ba 2003-11-23 devnull
892 056fe1ba 2003-11-23 devnull static Mem *
893 056fe1ba 2003-11-23 devnull memalloc(int n, int pos)
894 056fe1ba 2003-11-23 devnull {
895 056fe1ba 2003-11-23 devnull Mem *m;
896 056fe1ba 2003-11-23 devnull int nn;
897 056fe1ba 2003-11-23 devnull
898 056fe1ba 2003-11-23 devnull if(n < 0 || n > MaxFragSize) {
899 056fe1ba 2003-11-23 devnull werrstr(EPacketSize);
900 056fe1ba 2003-11-23 devnull return 0;
901 056fe1ba 2003-11-23 devnull }
902 056fe1ba 2003-11-23 devnull if(n <= SmallMemSize) {
903 056fe1ba 2003-11-23 devnull lock(&freelist.lk);
904 056fe1ba 2003-11-23 devnull m = freelist.smallmem;
905 056fe1ba 2003-11-23 devnull if(m != nil)
906 056fe1ba 2003-11-23 devnull freelist.smallmem = m->next;
907 056fe1ba 2003-11-23 devnull else
908 056fe1ba 2003-11-23 devnull freelist.nsmallmem++;
909 056fe1ba 2003-11-23 devnull unlock(&freelist.lk);
910 056fe1ba 2003-11-23 devnull nn = SmallMemSize;
911 056fe1ba 2003-11-23 devnull } else {
912 056fe1ba 2003-11-23 devnull lock(&freelist.lk);
913 056fe1ba 2003-11-23 devnull m = freelist.bigmem;
914 056fe1ba 2003-11-23 devnull if(m != nil)
915 056fe1ba 2003-11-23 devnull freelist.bigmem = m->next;
916 056fe1ba 2003-11-23 devnull else
917 056fe1ba 2003-11-23 devnull freelist.nbigmem++;
918 056fe1ba 2003-11-23 devnull unlock(&freelist.lk);
919 056fe1ba 2003-11-23 devnull nn = BigMemSize;
920 056fe1ba 2003-11-23 devnull }
921 056fe1ba 2003-11-23 devnull
922 056fe1ba 2003-11-23 devnull if(m == nil) {
923 056fe1ba 2003-11-23 devnull m = vtbrk(sizeof(Mem));
924 056fe1ba 2003-11-23 devnull m->bp = vtbrk(nn);
925 056fe1ba 2003-11-23 devnull m->ep = m->bp + nn;
926 056fe1ba 2003-11-23 devnull }
927 056fe1ba 2003-11-23 devnull assert(m->ref == 0);
928 056fe1ba 2003-11-23 devnull m->ref = 1;
929 056fe1ba 2003-11-23 devnull
930 056fe1ba 2003-11-23 devnull switch(pos) {
931 056fe1ba 2003-11-23 devnull default:
932 056fe1ba 2003-11-23 devnull assert(0);
933 056fe1ba 2003-11-23 devnull case PFront:
934 056fe1ba 2003-11-23 devnull m->rp = m->bp;
935 056fe1ba 2003-11-23 devnull break;
936 056fe1ba 2003-11-23 devnull case PMiddle:
937 056fe1ba 2003-11-23 devnull /* leave a little bit at end */
938 056fe1ba 2003-11-23 devnull m->rp = m->ep - n - 32;
939 056fe1ba 2003-11-23 devnull break;
940 056fe1ba 2003-11-23 devnull case PEnd:
941 056fe1ba 2003-11-23 devnull m->rp = m->ep - n;
942 056fe1ba 2003-11-23 devnull break;
943 056fe1ba 2003-11-23 devnull }
944 056fe1ba 2003-11-23 devnull /* check we did not blow it */
945 056fe1ba 2003-11-23 devnull if(m->rp < m->bp)
946 056fe1ba 2003-11-23 devnull m->rp = m->bp;
947 056fe1ba 2003-11-23 devnull m->wp = m->rp + n;
948 056fe1ba 2003-11-23 devnull assert(m->rp >= m->bp && m->wp <= m->ep);
949 056fe1ba 2003-11-23 devnull return m;
950 056fe1ba 2003-11-23 devnull }
951 056fe1ba 2003-11-23 devnull
952 056fe1ba 2003-11-23 devnull static void
953 056fe1ba 2003-11-23 devnull memfree(Mem *m)
954 056fe1ba 2003-11-23 devnull {
955 056fe1ba 2003-11-23 devnull lock(&m->lk);
956 056fe1ba 2003-11-23 devnull m->ref--;
957 056fe1ba 2003-11-23 devnull if(m->ref > 0) {
958 056fe1ba 2003-11-23 devnull unlock(&m->lk);
959 056fe1ba 2003-11-23 devnull return;
960 056fe1ba 2003-11-23 devnull }
961 056fe1ba 2003-11-23 devnull unlock(&m->lk);
962 056fe1ba 2003-11-23 devnull assert(m->ref == 0);
963 056fe1ba 2003-11-23 devnull
964 8baa0cbd 2004-06-09 devnull /* memset(m->bp, 0xEF, m->ep-m->bp); */
965 056fe1ba 2003-11-23 devnull switch(m->ep - m->bp) {
966 056fe1ba 2003-11-23 devnull default:
967 056fe1ba 2003-11-23 devnull assert(0);
968 056fe1ba 2003-11-23 devnull case SmallMemSize:
969 056fe1ba 2003-11-23 devnull lock(&freelist.lk);
970 056fe1ba 2003-11-23 devnull m->next = freelist.smallmem;
971 056fe1ba 2003-11-23 devnull freelist.smallmem = m;
972 056fe1ba 2003-11-23 devnull unlock(&freelist.lk);
973 056fe1ba 2003-11-23 devnull break;
974 056fe1ba 2003-11-23 devnull case BigMemSize:
975 056fe1ba 2003-11-23 devnull lock(&freelist.lk);
976 056fe1ba 2003-11-23 devnull m->next = freelist.bigmem;
977 056fe1ba 2003-11-23 devnull freelist.bigmem = m;
978 056fe1ba 2003-11-23 devnull unlock(&freelist.lk);
979 056fe1ba 2003-11-23 devnull break;
980 056fe1ba 2003-11-23 devnull }
981 056fe1ba 2003-11-23 devnull }
982 056fe1ba 2003-11-23 devnull
983 056fe1ba 2003-11-23 devnull static int
984 056fe1ba 2003-11-23 devnull memhead(Mem *m, uchar *rp, int n)
985 056fe1ba 2003-11-23 devnull {
986 8baa0cbd 2004-06-09 devnull fprint(2, "memhead called\n");
987 8baa0cbd 2004-06-09 devnull abort();
988 056fe1ba 2003-11-23 devnull lock(&m->lk);
989 056fe1ba 2003-11-23 devnull if(m->rp != rp) {
990 056fe1ba 2003-11-23 devnull unlock(&m->lk);
991 056fe1ba 2003-11-23 devnull return -1;
992 056fe1ba 2003-11-23 devnull }
993 056fe1ba 2003-11-23 devnull m->rp -= n;
994 056fe1ba 2003-11-23 devnull unlock(&m->lk);
995 056fe1ba 2003-11-23 devnull return 0;
996 056fe1ba 2003-11-23 devnull }
997 056fe1ba 2003-11-23 devnull
998 056fe1ba 2003-11-23 devnull static int
999 056fe1ba 2003-11-23 devnull memtail(Mem *m, uchar *wp, int n)
1000 056fe1ba 2003-11-23 devnull {
1001 8baa0cbd 2004-06-09 devnull fprint(2, "memtail called\n");
1002 8baa0cbd 2004-06-09 devnull abort();
1003 056fe1ba 2003-11-23 devnull lock(&m->lk);
1004 056fe1ba 2003-11-23 devnull if(m->wp != wp) {
1005 056fe1ba 2003-11-23 devnull unlock(&m->lk);
1006 056fe1ba 2003-11-23 devnull return -1;
1007 056fe1ba 2003-11-23 devnull }
1008 056fe1ba 2003-11-23 devnull m->wp += n;
1009 056fe1ba 2003-11-23 devnull unlock(&m->lk);
1010 056fe1ba 2003-11-23 devnull return 0;
1011 056fe1ba 2003-11-23 devnull }
1012 8baa0cbd 2004-06-09 devnull
1013 e5d47e6e 2004-12-28 devnull #if 0
1014 8baa0cbd 2004-06-09 devnull static void
1015 8baa0cbd 2004-06-09 devnull checkpacket(Packet *p)
1016 8baa0cbd 2004-06-09 devnull {
1017 8baa0cbd 2004-06-09 devnull int s, as;
1018 8baa0cbd 2004-06-09 devnull Frag *f;
1019 8baa0cbd 2004-06-09 devnull Frag *ff;
1020 8baa0cbd 2004-06-09 devnull
1021 8baa0cbd 2004-06-09 devnull s = 0;
1022 8baa0cbd 2004-06-09 devnull as = 0;
1023 8baa0cbd 2004-06-09 devnull ff=p->first;
1024 8baa0cbd 2004-06-09 devnull for(f=p->first; f; ff=f,f=f->next){
1025 8baa0cbd 2004-06-09 devnull assert(f->p == p);
1026 8baa0cbd 2004-06-09 devnull s += FRAGSIZE(f);
1027 8baa0cbd 2004-06-09 devnull as += FRAGASIZE(f);
1028 8baa0cbd 2004-06-09 devnull }
1029 8baa0cbd 2004-06-09 devnull assert(s == p->size);
1030 8baa0cbd 2004-06-09 devnull assert(as == p->asize);
1031 8baa0cbd 2004-06-09 devnull if(p->first)
1032 8baa0cbd 2004-06-09 devnull assert(ff==p->last);
1033 8baa0cbd 2004-06-09 devnull }
1034 e5d47e6e 2004-12-28 devnull #endif