/[smeserver]/rpms/diald/sme7/diald-1.0.buffer.patch
ViewVC logotype

Contents of /rpms/diald/sme7/diald-1.0.buffer.patch

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (show annotations) (download)
Tue Jun 12 14:58:57 2007 UTC (17 years, 5 months ago) by slords
Branch: MAIN
CVS Tags: diald-1_0-3_el4_sme, HEAD
Import on branch sme7 of package diald-1.0-3.el4.sme.src.rpm

1 diff -ru diald-1.0.orig/buffer.c diald-1.0/buffer.c
2 --- diald-1.0.orig/buffer.c 2001-06-16 15:51:39.000000000 -0400
3 +++ diald-1.0/buffer.c 2005-10-04 10:38:22.331362000 -0400
4 @@ -3,6 +3,7 @@
5 *
6 * Copyright (c) 1994, 1995, 1996 Eric Schenk.
7 * Copyright (c) 1999 Mike Jagdis.
8 + * Copyright (c) 2002 Jason Turner.
9 * All rights reserved. Please see the file LICENSE which should be
10 * distributed with this software for terms of use.
11 */
12 @@ -11,90 +12,195 @@
13
14 #include <diald.h>
15
16 +#define BUFFER_CHUNK_SIZE_MAX 4096
17
18 -#define B(i) buffer[(i)%buffer_size]
19 -
20 -static int oldsize = 0;
21 -static unsigned char *buffer = 0;
22 -static int head = 0;
23 -static int used = 0;
24 -static int tail = 0;
25 +#ifndef UINT_MAX
26 +#define UINT_MAX (~0U)
27 +#endif
28
29 -void buffer_init(int *var, char **argv)
30 -{
31 - buffer_size = atoi(*argv);
32 - if (buffer_size != oldsize) {
33 - if (buffer)
34 - free(buffer);
35 - buffer = malloc(buffer_size);
36 - oldsize = buffer_size;
37 +struct bpkt_hdr { /* Buffered packet header */
38 + unsigned long expires; /* When it expires in uptime secs */
39 + unsigned int len; /* Length of following packet,
40 + * up to BUFFER_CHUNK_SIZE_MAX */
41 +};
42 +
43 +static char *buffer = 0; /* start address of ring buffer */
44 +static char *buffer_end = 0; /* end address (+1) of ring buffer */
45 +static unsigned int true_size = 0; /* actual size of buffer */
46 +static unsigned int used = 0; /* bytes used */
47 +static unsigned int head = 0; /* read offset */
48 +static unsigned int tail = 0; /* write offset */
49 +
50 +/* buffer_setup()
51 + * Create/recreate/delete the buffer and setup pointers.
52 + * Returns the actual buffer size.
53 + * The buffer_size variable is declared in diald.h and is given an initial
54 + * value in options.c .
55 + */
56 +static unsigned int buffer_setup() {
57 + if ( buffer_size < 0 || buffer_size > UINT_MAX ) {
58 + mon_syslog(LOG_ERR,"Ignoring invalid buffer_size request.");
59 + } else {
60 + /* discard existing buffer and any contents */
61 + if (buffer) {
62 + free(buffer);
63 + buffer = 0;
64 + }
65 + true_size = 0; used = 0; head = 0; tail = 0;
66 + if (buffer_size) {
67 + /* create new buffer */
68 + if (buffer = malloc(buffer_size)) {
69 + true_size = buffer_size;
70 + buffer_end = buffer + true_size;
71 + } else {
72 + mon_syslog(LOG_ERR, "Out of memory! Cannot create ring buffer.");
73 + /* This is not fatal. diald will run fine without the buffer. */
74 + }
75 + }
76 }
77 + return true_size;
78 }
79
80 +/* buffer_check()
81 + * If there is no buffer_size param in the config file, the buffer is not
82 + * initially set up!
83 + * So call this from forward_buffer() and buffer_packet()
84 + */
85 static void buffer_check()
86 {
87 - if (!buffer) {
88 - buffer = malloc(buffer_size);
89 - oldsize = buffer_size;
90 + if (buffer)
91 + return;
92 + if (!buffer_setup()) {
93 + /* if we cannot create a buffer, then disable the feature to avoid
94 + * repeated calls. */
95 + buffer_packets = 0;
96 + mon_syslog(LOG_WARNING,"No buffer: buffer-packets feature disabled.");
97 }
98 }
99
100 +/* buffer_write()
101 + * Write data to the ring buffer, adjust tail offset and space used
102 + * Should not be called unless sure there is enough free space
103 + */
104 +static void buffer_write(unsigned int count, char *pkt) {
105 + char *write_ptr = buffer + tail;
106 +
107 + if (write_ptr + count > buffer_end) {
108 + unsigned int count2end = buffer_end - write_ptr;
109 + memcpy(write_ptr, pkt, count2end);
110 + memcpy(buffer, pkt + count2end, count - count2end);
111 + } else {
112 + memcpy(write_ptr, pkt, count);
113 + }
114 + tail = (tail+count)%true_size;
115 + used += count;
116 +}
117
118 -void buffer_packet(unsigned int len,unsigned char *pkt)
119 +/* buffer_read()
120 + * Read bytes from ring buffer. Do not delete.
121 + * Should not be called unless used is positive.
122 + */
123 +static void buffer_read(unsigned int count, char *pkt) {
124 + char *read_ptr = buffer + head;
125 +
126 + if (read_ptr + count > buffer_end) {
127 + unsigned int count2end = buffer_end - read_ptr;
128 + memcpy(pkt, read_ptr, count2end);
129 + memcpy(pkt + count2end, buffer, count - count2end);
130 + } else {
131 + memcpy(pkt, read_ptr, count);
132 + }
133 +}
134 +
135 +/* buffer_dispose()
136 + * Delete from ring buffer by adjusting read offset
137 + */
138 +static void buffer_dispose(unsigned int count) {
139 + head = (head+count)%true_size;
140 + used -= count;
141 +}
142 +
143 +/* externally linked functions */
144 +
145 +/* buffer_init()
146 + * This is called when reading the config file or command line options.
147 + * There will be at least one argument, but the arg was not checked to be a
148 + * numeric string.
149 + */
150 +void buffer_init(int *var, char **argv)
151 +{
152 + buffer_size = strtol(*argv, NULL, 0);
153 + if (buffer_size != true_size)
154 + buffer_setup();
155 +}
156 +
157 +/* buffer_packet()
158 + * Place packet into the ring.
159 + */
160 +void buffer_packet(unsigned int len, unsigned char *pkt)
161 {
162 - unsigned int clen;
163 - unsigned long stamp;
164 + struct bpkt_hdr pkt_hdr;
165 unsigned long ctime = timestamp();
166 + unsigned int space_needed = len + sizeof(struct bpkt_hdr);
167 +
168 + if (len > BUFFER_CHUNK_SIZE_MAX) {
169 + mon_syslog(LOG_WARNING, "Packet too large to buffer: %d", len);
170 + return;
171 + }
172
173 buffer_check();
174 - if (len+6 > buffer_size) {
175 +
176 + if (space_needed > true_size) {
177 mon_syslog(LOG_NOTICE,
178 "Can't buffer packet of length %d, buffer too small",
179 len);
180 return;
181 }
182 +
183 + /* TODO
184 + * Add buffer filtering ?
185 + * eg. ntp packets do not fare well to long delays
186 + * The expires time could also be different for each packet.
187 + */
188 +
189 if (buffer_fifo_dispose) {
190 /* toss from the front of the buffer till we have space */
191 - while (used+len+6 > buffer_size) {
192 - clen = (B(head)<<8) | B(head+1);
193 - head = (head+6+clen)%buffer_size;
194 - used -= (6+clen);
195 + while (used + space_needed > true_size) {
196 + buffer_read(sizeof(struct bpkt_hdr), (char *)&pkt_hdr);
197 + buffer_dispose(sizeof(struct bpkt_hdr) + pkt_hdr.len);
198 }
199 } else {
200 + /* toss out expired packets from front of buffer
201 + * Any expired packets in the middle will be killed when forwarding
202 + */
203 for (;;) {
204 - clen = (B(head)<<8) | B(head+1);
205 - stamp = (B(head+2)<<24) | (B(head+3)<<16) | (B(head+4)<<8) | B(head+5);
206 - if (stamp+buffer_timeout >= ctime)
207 + if (!used)
208 + break;
209 + buffer_read(sizeof(struct bpkt_hdr), (char *)&pkt_hdr);
210 + if (pkt_hdr.expires >= ctime)
211 break;
212 - head = (head+6+clen)%buffer_size;
213 - used -= (6+clen);
214 + buffer_dispose(sizeof(struct bpkt_hdr) + pkt_hdr.len);
215 }
216 }
217 - if (used+len+6 <= buffer_size) {
218 - used = used + 6 + len;
219 - B(tail) = (len>>8)&0xff;
220 - B(tail+1) = len&0xff;
221 - B(tail+2) = (ctime>>24)&0xff;
222 - B(tail+3) = (ctime>>16)&0xff;
223 - B(tail+4) = (ctime>>8)&0xff;
224 - B(tail+5) = ctime&0xff;
225 - tail = (tail+6)%buffer_size;
226 - while (len--) {
227 - buffer[tail] = *pkt++;
228 - tail = (tail+1)%buffer_size;
229 - }
230 + if (used + space_needed <= true_size) {
231 + pkt_hdr.len = len;
232 + pkt_hdr.expires = ctime + buffer_timeout;
233 + buffer_write(sizeof(struct bpkt_hdr), (char *)&pkt_hdr);
234 + buffer_write(len, pkt);
235 } else {
236 mon_syslog(LOG_NOTICE,
237 "Can't buffer packet of length %d, only %d bytes available.",
238 - len,buffer_size-(used+6));
239 + len, true_size - ( used + sizeof(struct bpkt_hdr) ) );
240 }
241 }
242
243 +/* forward_buffer()
244 + * Clears ring buffer and sends unexpired packets on their way.
245 + */
246 void forward_buffer()
247 {
248 + struct bpkt_hdr pkt_hdr;
249 int forwarding = 0;
250 - unsigned int clen, i;
251 - unsigned long stamp;
252 unsigned long ctime = timestamp();
253 struct sockaddr_pkt sp;
254 #ifdef HAVE_AF_PACKET
255 @@ -102,7 +208,7 @@
256 #endif
257 struct sockaddr *to;
258 size_t to_len;
259 - unsigned char pkt[4096];
260 + char pkt[BUFFER_CHUNK_SIZE_MAX];
261
262 #ifdef __linux__
263 /* If we are using dynamic addresses we need to know whether we
264 @@ -141,19 +247,19 @@
265 }
266
267 while (used > 0) {
268 - clen = (B(head)<<8) | B(head+1);
269 - stamp = (B(head+2)<<24) | (B(head+3)<<16) | (B(head+4)<<8) | B(head+5);
270 - if (stamp+buffer_timeout >= ctime) {
271 + buffer_read(sizeof(struct bpkt_hdr), (char *)&pkt_hdr);
272 + buffer_dispose(sizeof(struct bpkt_hdr));
273 + if (pkt_hdr.expires >= ctime) {
274 unsigned short wprot;
275 - unsigned char *dpkt;
276 + char *dpkt;
277 unsigned int dlen;
278
279 - for (i = 0; i < clen; i++)
280 - pkt[i] = B(head+6+i);
281 + buffer_read(pkt_hdr.len, pkt);
282
283 + /* strip off the protocol from the raw packet */
284 wprot = *(unsigned short *)pkt;
285 dpkt = pkt + sizeof(unsigned short);
286 - dlen = clen - sizeof(unsigned short);
287 + dlen = pkt_hdr.len - sizeof(unsigned short);
288
289 /* If we are using dynamic addresses and forwarding traffic
290 * we send the packet back in to the kernel on the proxy so
291 @@ -180,7 +286,6 @@
292 mon_syslog(LOG_ERR,"Error forwarding data packet to physical device from buffer: %m");
293 }
294 }
295 - head = (head+6+clen)%buffer_size;
296 - used -= (6+clen);
297 + buffer_dispose(pkt_hdr.len);
298 }
299 }

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed