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>
23 int packetq_timeout
= -1;
30 int (*sender
)(int fd
, int fd_ctl
, void *packet
, int len
, void *data
, int port
);
38 struct packetqq
*next
;
41 static struct packetqq
*pqh
=NULL
;
42 static struct packetqq
*pqt
=NULL
;
43 static struct timeval last_try
;
45 void packetq_add(int (*sender
)(int fd
, int fd_ctl
, void *packet
, int len
, void *data
, int port
),
46 int fd
, int fd_ctl
, void *packet
, int len
, void *data
, int port
)
48 if (countq
< MAXQLEN
) {
49 struct packetqq
*new=malloc(sizeof(struct packetqq
));
50 void *packetcopy
=malloc(len
);
51 if (new != NULL
&& packetcopy
!= NULL
&& len
> 0) {
56 memcpy(packetcopy
,packet
,len
);
57 new->packet
=packetcopy
;
64 gettimeofday(&last_try
,NULL
);
65 packetq_timeout
=TIMEOUT
;
72 if (new != NULL
) free(new);
73 if (packetcopy
!= NULL
) free(packetcopy
);
78 static struct packetqq
*packetq_scantry(struct packetqq
*h
,struct packetqq
**t
,fd_set
*fds
)
81 int sendrv
=!(FD_ISSET(h
->fd
,fds
));
83 if ((sendrv
&& (sendrv
=h
->sender(h
->fd
,h
->fd_ctl
,h
->packet
,h
->len
,h
->data
,h
->port
)) == 0) /*send OK*/
84 || h
->times
<=0) { /*or max number of attempts reached*/
85 struct packetqq
*next
;
87 /* this error code is unreachable! (sendrv==0 here) */
90 printlog(LOG_WARNING
,"packetqueue port %d: %s",h
->port
,strerror(-sendrv
));
92 printlog(LOG_WARNING
,"packetqueue port %d: partial send (%d bytes lost)",h
->port
,sendrv
);
99 return packetq_scantry(next
,t
,fds
);
102 h
->next
=packetq_scantry(h
->next
,t
,fds
);
103 if (h
->next
== NULL
) *t
=h
;
110 void packetq_try(void)
113 struct timeval this_try
;
114 gettimeofday(&this_try
,NULL
);
115 packetq_timeout
=TIMEOUT
- ((this_try
.tv_sec
-last_try
.tv_sec
) * 1000 +
116 (this_try
.tv_usec
-last_try
.tv_usec
) / 1000);
117 if (packetq_timeout
<= 0) {
120 pqh
=packetq_scantry(pqh
,&pqt
,&fds
);
122 gettimeofday(&last_try
,NULL
);
123 packetq_timeout
=TIMEOUT
;
125 packetq_timeout
= -1;
130 static struct packetqq
*packetq_scandelfd(int fd
,struct packetqq
*h
,struct packetqq
**t
)
134 struct packetqq
*next
=h
->next
;
138 return packetq_scandelfd(fd
,next
,t
);
140 h
->next
=packetq_scandelfd(fd
,h
->next
,t
);
141 if (h
->next
== NULL
) *t
=h
;
148 void packetq_delfd(int fd
)
150 pqh
=packetq_scandelfd(fd
,pqh
,&pqt
);
152 packetq_timeout
= -1;