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

Annotation of /rpms/diald/sme8/diald-1.0.buffer.patch

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


Revision 1.1 - (hide annotations) (download)
Tue Jun 12 18:15:05 2007 UTC (17 years, 5 months ago) by slords
Branch: MAIN
CVS Tags: diald-1_0-3_el5_sme, HEAD
Import on branch sme8 of package diald-1.0-3.el5.sme.src.rpm

1 slords 1.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