2 * packetq - packet queue management. try to send packets several times before discarding.
3 * Copyright 2005 Renzo Davoli
4 * Licensed under the GPLv2
13 #include <sys/types.h>
24 int packetq_timeout
= -1;
31 int (*sender
)(int fd
, int fd_ctl
, void *packet
, int len
, void *data
, int port
);
39 struct packetqq
*next
;
42 static struct packetqq
*pqh
=NULL
;
43 static struct packetqq
*pqt
=NULL
;
44 static struct timeval last_try
;
46 void packetq_add(int (*sender
)(int fd
, int fd_ctl
, void *packet
, int len
, void *data
, int port
),
47 int fd
, int fd_ctl
, void *packet
, int len
, void *data
, int port
)
49 if (countq
< MAXQLEN
) {
50 struct packetqq
*new=malloc(sizeof(struct packetqq
));
51 void *packetcopy
=malloc(len
);
52 if (new != NULL
&& packetcopy
!= NULL
&& len
> 0) {
57 memcpy(packetcopy
,packet
,len
);
58 new->packet
=packetcopy
;
65 gettimeofday(&last_try
,NULL
);
66 packetq_timeout
=TIMEOUT
;
73 if (new != NULL
) free(new);
74 if (packetcopy
!= NULL
) free(packetcopy
);
79 static struct packetqq
*packetq_scantry(struct packetqq
*h
,struct packetqq
**t
,fd_set
*fds
)
82 int sendrv
=!(FD_ISSET(h
->fd
,fds
));
84 if ((sendrv
&& (sendrv
=h
->sender(h
->fd
,h
->fd_ctl
,h
->packet
,h
->len
,h
->data
,h
->port
)) == 0) /*send OK*/
85 || h
->times
<=0) { /*or max number of attempts reached*/
86 struct packetqq
*next
;
88 /* this error code is unreachable! (sendrv==0 here) */
91 printlog(LOG_WARNING
,"packetqueue port %d: %s",h
->port
,strerror(-sendrv
));
93 printlog(LOG_WARNING
,"packetqueue port %d: partial send (%d bytes lost)",h
->port
,sendrv
);
100 return packetq_scantry(next
,t
,fds
);
103 h
->next
=packetq_scantry(h
->next
,t
,fds
);
104 if (h
->next
== NULL
) *t
=h
;
111 void packetq_try(void)
114 struct timeval this_try
;
115 gettimeofday(&this_try
,NULL
);
116 packetq_timeout
=TIMEOUT
- ((this_try
.tv_sec
-last_try
.tv_sec
) * 1000 +
117 (this_try
.tv_usec
-last_try
.tv_usec
) / 1000);
118 if (packetq_timeout
<= 0) {
121 pqh
=packetq_scantry(pqh
,&pqt
,&fds
);
123 gettimeofday(&last_try
,NULL
);
124 packetq_timeout
=TIMEOUT
;
126 packetq_timeout
= -1;
131 static struct packetqq
*packetq_scandelfd(int fd
,struct packetqq
*h
,struct packetqq
**t
)
135 struct packetqq
*next
=h
->next
;
139 return packetq_scandelfd(fd
,next
,t
);
141 h
->next
=packetq_scandelfd(fd
,h
->next
,t
);
142 if (h
->next
== NULL
) *t
=h
;
149 void packetq_delfd(int fd
)
151 pqh
=packetq_scandelfd(fd
,pqh
,&pqt
);
153 packetq_timeout
= -1;