minor code cleanup
[vde.git] / vde-2 / src / vde_switch / packetq.c
blob12cfae0e40a9190055529f7e48d9a26c48ba272c
1 /*
2 * packetq - packet queue management. try to send packets several times before discarding.
3 * Copyright 2005 Renzo Davoli
4 * Licensed under the GPLv2
5 */
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <sys/time.h>
11 #include <time.h>
12 #include <sys/types.h>
13 #include <unistd.h>
14 #include <errno.h>
15 #include <syslog.h>
17 #include <config.h>
18 #include <vde.h>
19 #include <vdecommon.h>
21 #include "consmgmt.h"
23 #ifdef VDE_PQ
24 #include "packetq.h"
26 int packetq_timeout= -1;
27 static int countq;
28 #define TIMEOUT 5
29 #define TIMES 10
30 #define MAXQLEN 4192
32 struct packetqq {
33 int (*sender)(int fd, int fd_ctl, void *packet, int len, void *data, int port);
34 int fd;
35 int fd_ctl;
36 void *packet;
37 int len;
38 void *data;
39 int port;
40 int times;
41 struct packetqq *next;
44 static struct packetqq *pqh=NULL;
45 static struct packetqq *pqt=NULL;
46 static struct timeval last_try;
48 void packetq_add(int (*sender)(int fd, int fd_ctl, void *packet, int len, void *data, int port),
49 int fd, int fd_ctl, void *packet, int len, void *data, int port)
51 if (countq < MAXQLEN) {
52 struct packetqq *new=malloc(sizeof(struct packetqq));
53 void *packetcopy=malloc(len);
54 if (new != NULL && packetcopy != NULL && len > 0) {
55 countq++;
56 new->sender=sender;
57 new->fd=fd;
58 new->fd_ctl=fd_ctl;
59 memcpy(packetcopy,packet,len);
60 new->packet=packetcopy;
61 new->len=len;
62 new->data=data;
63 new->port=port;
64 new->times=TIMES;
65 new->next=NULL;
66 if (pqh==NULL) {
67 gettimeofday(&last_try,NULL);
68 packetq_timeout=TIMEOUT;
69 pqh=pqt=new;
70 } else {
71 pqt->next=new;
72 pqt=new;
74 } else {
75 if (new != NULL) free(new);
76 if (packetcopy != NULL) free(packetcopy);
81 static struct packetqq *packetq_scantry(struct packetqq *h,struct packetqq **t,fd_set *fds)
83 if (h != NULL) {
84 int sendrv=!(FD_ISSET(h->fd,fds));
85 h->times--;
86 if ((sendrv && (sendrv=h->sender(h->fd,h->fd_ctl,h->packet,h->len,h->data,h->port)) == 0) /*send OK*/
87 || h->times<=0) { /*or max number of attempts reached*/
88 struct packetqq *next;
89 next=h->next;
90 countq--;
91 free(h->packet);
92 free(h);
93 return packetq_scantry(next,t,fds);
94 } else {
95 FD_SET(h->fd,fds);
96 h->next=packetq_scantry(h->next,t,fds);
97 if (h->next == NULL) *t=h;
98 return h;
100 } else
101 return NULL;
104 void packetq_try(void)
106 if (pqh != NULL) {
107 struct timeval this_try;
108 gettimeofday(&this_try,NULL);
109 packetq_timeout=TIMEOUT - ((this_try.tv_sec-last_try.tv_sec) * 1000 +
110 (this_try.tv_usec-last_try.tv_usec) / 1000);
111 if (packetq_timeout <= 0) {
112 fd_set fds;
113 FD_ZERO(&fds);
114 pqh=packetq_scantry(pqh,&pqt,&fds);
115 if (pqh != NULL) {
116 gettimeofday(&last_try,NULL);
117 packetq_timeout=TIMEOUT;
118 } else
119 packetq_timeout = -1;
124 static struct packetqq *packetq_scandelfd(int fd,struct packetqq *h,struct packetqq **t)
126 if (h != NULL) {
127 if (fd == h->fd) {
128 struct packetqq *next=h->next;
129 countq--;
130 free(h->packet);
131 free(h);
132 return packetq_scandelfd(fd,next,t);
133 } else {
134 h->next=packetq_scandelfd(fd,h->next,t);
135 if (h->next == NULL) *t=h;
136 return h;
138 } else
139 return NULL;
142 void packetq_delfd(int fd)
144 pqh=packetq_scandelfd(fd,pqh,&pqt);
145 if (pqh == NULL)
146 packetq_timeout = -1;
149 int packetq_count()
151 return countq;
153 #endif