2
* packetq - packet queue management. try to send packets several times before discarding.
3
* Copyright 2005 Renzo Davoli
4
* Licensed under the GPLv2
12
#include <sys/types.h>
19
#include <vdecommon.h>
26
int packetq_timeout= -1;
33
int (*sender)(int fd, int fd_ctl, void *packet, int len, void *data, int port);
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) {
59
memcpy(packetcopy,packet,len);
60
new->packet=packetcopy;
67
gettimeofday(&last_try,NULL);
68
packetq_timeout=TIMEOUT;
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)
84
int sendrv=!(FD_ISSET(h->fd,fds));
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;
90
/* this error code is unreachable! (sendrv==0 here) */
93
printlog(LOG_WARNING,"packetqueue port %d: %s",h->port,strerror(-sendrv));
95
printlog(LOG_WARNING,"packetqueue port %d: partial send (%d bytes lost)",h->port,sendrv);
102
return packetq_scantry(next,t,fds);
105
h->next=packetq_scantry(h->next,t,fds);
106
if (h->next == NULL) *t=h;
113
void packetq_try(void)
116
struct timeval this_try;
117
gettimeofday(&this_try,NULL);
118
packetq_timeout=TIMEOUT - ((this_try.tv_sec-last_try.tv_sec) * 1000 +
119
(this_try.tv_usec-last_try.tv_usec) / 1000);
120
if (packetq_timeout <= 0) {
123
pqh=packetq_scantry(pqh,&pqt,&fds);
125
gettimeofday(&last_try,NULL);
126
packetq_timeout=TIMEOUT;
128
packetq_timeout = -1;
133
static struct packetqq *packetq_scandelfd(int fd,struct packetqq *h,struct packetqq **t)
137
struct packetqq *next=h->next;
141
return packetq_scandelfd(fd,next,t);
143
h->next=packetq_scandelfd(fd,h->next,t);
144
if (h->next == NULL) *t=h;
151
void packetq_delfd(int fd)
153
pqh=packetq_scandelfd(fd,pqh,&pqt);
155
packetq_timeout = -1;