while (vpninfo->dtls_fd == -1 && vpninfo->outgoing_queue) {
struct pkt *this = vpninfo->outgoing_queue;
vpninfo->outgoing_queue = this->next;
+ vpninfo->outgoing_qlen--;
if (vpninfo->deflate) {
unsigned char *adler;
int ret;
vpninfo->outgoing_queue = this->next;
+ vpninfo->outgoing_qlen--;
/* One byte of header */
this->hdr[7] = AC_PKT_DATA;
ERR_print_errors_fp(stderr);
dtls_restart(vpninfo);
vpninfo->outgoing_queue = this;
+ vpninfo->outgoing_qlen++;
}
return 1;
}
did_work += cstp_mainloop(vpninfo, &timeout);
if (vpninfo->quit_reason)
break;
-
+
+ /* Tun must be last because it will set/clear its bit
+ in the select_rfds according to the queue length */
did_work += tun_mainloop(vpninfo, &timeout);
if (vpninfo->quit_reason)
break;
#define KA_KEEPALIVE 3
#define KA_REKEY 4
+
+#define MAX_Q_LEN 10
+
struct keepalive_info {
int dpd;
int keepalive;
struct pkt *incoming_queue;
struct pkt *outgoing_queue;
+ int outgoing_qlen;
socklen_t peer_addrlen;
struct sockaddr *peer_addr;
int len;
int work_done = 0;
- while ( (len = read(vpninfo->tun_fd, buf, sizeof(buf))) > 0) {
- queue_new_packet(&vpninfo->outgoing_queue, AF_INET, buf, len);
- work_done = 1;
+ if (FD_ISSET(vpninfo->tun_fd, &vpninfo->select_rfds)) {
+ while ((len = read(vpninfo->tun_fd, buf, sizeof(buf))) > 0) {
+ if (queue_new_packet(&vpninfo->outgoing_queue, AF_INET, buf, len))
+ break;
+
+ work_done = 1;
+ vpninfo->outgoing_qlen++;
+ if (vpninfo->outgoing_qlen == MAX_Q_LEN) {
+ FD_CLR(vpninfo->tun_fd, &vpninfo->select_rfds);
+ break;
+ }
+ }
+ } else if (vpninfo->outgoing_qlen < MAX_Q_LEN) {
+ FD_SET(vpninfo->tun_fd, &vpninfo->select_rfds);
}
/* The kernel returns -ENOMEM when the queue is full, so theoretically