int queue_new_packet(struct pkt **q, int type, void *buf, int len);
void queue_packet(struct pkt **q, struct pkt *new);
int keepalive_action(struct keepalive_info *ka, int *timeout);
+int ka_stalled_dpd_time(struct keepalive_info *ka, int *timeout);
/* xml.c */
int config_lookup_host(struct anyconnect_info *vpninfo, const char *host);
return 0;
}
+/* Called when the socket is unwritable, to get the deadline for DPD.
+ Returns 1 if DPD deadline has already arrived. */
+int ka_stalled_dpd_time(struct keepalive_info *ka, int *timeout)
+{
+ time_t now, due;
+
+ if (!ka->dpd) {
+ printf("no dpd\n");
+ return 0;
+ }
+
+ time(&now);
+ due = ka->last_rx + (2 * ka->dpd);
+
+ if (now > due)
+ return 1;
+
+ printf("ka_stalled in %d seconds\n", (int)(due - now));
+ if (*timeout > (due - now) * 1000)
+ *timeout = (due - now) * 1000;
+
+ return 0;
+}
+
+
int keepalive_action(struct keepalive_info *ka, int *timeout)
{
time_t now = time(NULL);
if (vpninfo->current_ssl_pkt) {
handle_outgoing:
vpninfo->ssl_times.last_tx = time(NULL);
+ vpninfo->pfds[vpninfo->ssl_pfd].events &= ~POLLOUT;
ret = SSL_write(vpninfo->https_ssl,
vpninfo->current_ssl_pkt->hdr,
vpninfo->current_ssl_pkt->len + 8);
if (ret <= 0) {
ret = SSL_get_error(vpninfo->https_ssl, ret);
switch (ret) {
- case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
- /* FIXME: Set pollfd flags accordingly */
+ /* Waiting for the socket to become writable -- it's
+ probably stalled, and/or the buffers are full */
+ printf("SSL want write\n");
+ vpninfo->pfds[vpninfo->ssl_pfd].events |= POLLOUT;
+ case SSL_ERROR_WANT_READ:
+ if (ka_stalled_dpd_time(&vpninfo->ssl_times, timeout)) {
+ vpninfo->quit_reason = "SSL DPD detected dead peer";
+ return 1;
+ }
return work_done;
default:
fprintf(stderr, "SSL_write failed: %d", ret);
work_done = 1;
break;
-
case KA_DPD_DEAD:
fprintf(stderr, "CSTP Dead Peer Detection detected dead peer!\n");
vpninfo->quit_reason = "SSL DPD detected dead peer";