1 #include "burp.h"
2 #include "alloc.h"
3 #include "log.h"
4 #include "sbuf.h"
5 #include "slist.h"
6 #include "protocol2/blist.h"
7
slist_alloc(void)8 struct slist *slist_alloc(void)
9 {
10 struct slist *slist=NULL;
11 if(!(slist=(struct slist *)calloc_w(1, sizeof(struct slist), __func__))
12 || !(slist->blist=blist_alloc()))
13 slist_free(&slist);
14 return slist;
15 }
16
slist_free(struct slist ** slist)17 void slist_free(struct slist **slist)
18 {
19 struct sbuf *sb;
20 struct sbuf *shead;
21 if(!slist || !*slist)
22 return;
23 blist_free(&(*slist)->blist);
24 shead=(*slist)->head;
25 while(shead)
26 {
27 sb=shead;
28 shead=shead->next;
29 sbuf_free(&sb);
30 }
31 free_v((void **)slist);
32 }
33
slist_add_sbuf(struct slist * slist,struct sbuf * sb)34 void slist_add_sbuf(struct slist *slist, struct sbuf *sb)
35 {
36 if(slist->tail)
37 {
38 // Add to the end of the list.
39 slist->tail->next=sb;
40 slist->tail=sb;
41 // Markers might have fallen off the end. Start them again
42 // on the tail.
43 if(!slist->last_requested)
44 slist->last_requested=slist->tail;
45 if(!slist->add_sigs_here)
46 slist->add_sigs_here=slist->tail;
47 if(!slist->blks_to_request)
48 slist->blks_to_request=slist->tail;
49 if(!slist->blks_to_send)
50 slist->blks_to_send=slist->tail;
51 }
52 else
53 {
54 // Start the list.
55 slist->head=sb;
56 slist->tail=sb;
57 // Pointers to the head that can move along the list
58 // at a different rate.
59 slist->last_requested=sb;
60 slist->add_sigs_here=sb;
61 slist->blks_to_request=sb;
62 slist->blks_to_send=sb;
63 }
64 slist->count++;
65 }
66
adjust_dropped_markers(struct slist * slist,struct sbuf * sb)67 static void adjust_dropped_markers(struct slist *slist, struct sbuf *sb)
68 {
69 if(sb==slist->tail)
70 slist->tail=sb->next;
71 if(sb==slist->last_requested)
72 slist->last_requested=sb->next;
73 if(sb==slist->add_sigs_here)
74 slist->add_sigs_here=sb->next;
75 if(sb==slist->blks_to_request)
76 slist->blks_to_request=sb->next;
77 if(sb==slist->blks_to_send)
78 slist->blks_to_send=sb->next;
79 }
80
slist_del_sbuf(struct slist * slist,struct sbuf * sb)81 int slist_del_sbuf(struct slist *slist, struct sbuf *sb)
82 {
83 struct sbuf *s;
84 if(!slist)
85 return 0;
86 if(sb->protocol2->bstart
87 || sb->protocol2->bend
88 || sb->protocol2->bsighead)
89 {
90 logp("Cannot delete sbuf with blk markers: %s\n",
91 iobuf_to_printable(&sb->path));
92 return -1;
93 }
94
95 if(slist->head==sb)
96 {
97 // There is one entry in the list.
98 slist->head=slist->head->next;
99 slist->count--;
100 }
101 else
102 {
103 for(s=slist->head; s; s=s->next)
104 {
105 if(s->next!=sb) continue;
106 s->next=sb->next;
107 if(!sb->next)
108 slist->tail=s;
109 slist->count--;
110 break;
111 }
112 }
113
114 // It is possible for the markers to drop behind.
115 adjust_dropped_markers(slist, sb);
116
117 return 0;
118 }
119
slist_del_sbuf_by_index(struct slist * slist,uint64_t index)120 int slist_del_sbuf_by_index(struct slist *slist, uint64_t index)
121 {
122 struct sbuf *sb;
123 for(sb=slist->head; sb; sb=sb->next)
124 {
125 if(sb->protocol2->index==index)
126 {
127 if(slist_del_sbuf(slist, sb))
128 return -1;
129 sbuf_free(&sb);
130 break;
131 }
132 }
133 return 0;
134 }
135
slist_advance(struct slist * slist)136 void slist_advance(struct slist *slist)
137 {
138 struct sbuf *sb;
139 sb=slist->head;
140
141 // It is possible for the markers to drop behind.
142 adjust_dropped_markers(slist, sb);
143
144 slist->head=sb->next;
145
146 slist->count--;
147
148 sbuf_free(&sb);
149 }
150