Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
use generic KA stuff for cstp
  • Loading branch information
David Woodhouse authored and David Woodhouse committed Oct 2, 2008
1 parent cea4b05 commit 9563070
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 72 deletions.
9 changes: 6 additions & 3 deletions dtls.c
Expand Up @@ -280,6 +280,8 @@ int dtls_mainloop(struct anyconnect_info *vpninfo, int *timeout)
}
}

if (verbose)
printf("Process DTLS keepalive...\n");
switch (keepalive_action(&vpninfo->dtls_times, timeout)) {
case KA_REKEY:
if (verbose)
Expand Down Expand Up @@ -321,14 +323,14 @@ int dtls_mainloop(struct anyconnect_info *vpninfo, int *timeout)
break;

case KA_KEEPALIVE:
if (verbose)
printf("Send DTLS Keepalive\n");

/* No need to send an explicit keepalive
if we have real data to send */
if (vpninfo->outgoing_queue)
break;

if (verbose)
printf("Send DTLS Keepalive\n");

magic_pkt = AC_PKT_KEEPALIVE;
SSL_write(vpninfo->dtls_ssl, &magic_pkt, 1);
time(&vpninfo->dtls_times.last_tx);
Expand All @@ -339,6 +341,7 @@ int dtls_mainloop(struct anyconnect_info *vpninfo, int *timeout)
;
}

/* Service outgoing packet queue */
while (vpninfo->outgoing_queue) {
struct pkt *this = vpninfo->outgoing_queue;
int ret;
Expand Down
125 changes: 56 additions & 69 deletions ssl.c
Expand Up @@ -529,6 +529,14 @@ static int inflate_and_queue_packet(struct anyconnect_info *vpninfo, int type, v
return 0;
}

static struct pkt keepalive_pkt = {
.hdr = { 'S', 'T', 'F', 1, 0, 0, AC_PKT_KEEPALIVE, 0 },
};

static struct pkt dpd_pkt = {
.hdr = { 'S', 'T', 'F', 1, 0, 0, AC_PKT_DPD_OUT, 0 },
};

int ssl_mainloop(struct anyconnect_info *vpninfo, int *timeout)
{
unsigned char buf[16384];
Expand Down Expand Up @@ -561,7 +569,7 @@ int ssl_mainloop(struct anyconnect_info *vpninfo, int *timeout)
switch(buf[6]) {
case 4: /* Keepalive response */
if (verbose)
printf("Got SSL DPD response\n");
printf("Got CSTP DPD response\n");
continue;

case 0: /* Uncompressed Data */
Expand Down Expand Up @@ -627,12 +635,57 @@ int ssl_mainloop(struct anyconnect_info *vpninfo, int *timeout)
vpninfo->quit_reason = "Internal error";
return 1;
}
if (vpninfo->current_ssl_pkt != vpninfo->deflate_pkt)
/* Don't free the 'special' packets */
if (vpninfo->current_ssl_pkt != vpninfo->deflate_pkt &&
vpninfo->current_ssl_pkt != &dpd_pkt &&
vpninfo->current_ssl_pkt != &keepalive_pkt)
free(vpninfo->current_ssl_pkt);

vpninfo->current_ssl_pkt = NULL;
}

/* Don't send data over SSL if we have DTLS */
if (verbose)
printf("Process CSTP keepalive...\n");
switch (keepalive_action(&vpninfo->ssl_times, timeout)) {
case KA_REKEY:
/* Not that this will ever happen; we don't even process
the setting when we're asked for it. */
fprintf(stderr, "CSTP rekey due but we don't know how\n");
time(&vpninfo->ssl_times.last_rekey);
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";
/* FIXME: We should try to reconnect with the same cookie */
return 1;

case KA_DPD:
if (verbose)
printf("Send CSTP DPD\n");

vpninfo->current_ssl_pkt = &dpd_pkt;
goto handle_outgoing;

case KA_KEEPALIVE:
/* No need to send an explicit keepalive
if we have real data to send */
if (vpninfo->dtls_fd == -1 && vpninfo->outgoing_queue)
break;

if (verbose)
printf("Send CSTP Keepalive\n");

vpninfo->current_ssl_pkt = &keepalive_pkt;
goto handle_outgoing;

case KA_NONE:
;
}

/* Service outgoing packet queue, if no DTLS */
while (vpninfo->dtls_fd == -1 && vpninfo->outgoing_queue) {
struct pkt *this = vpninfo->outgoing_queue;
vpninfo->outgoing_queue = this->next;
Expand Down Expand Up @@ -688,72 +741,6 @@ int ssl_mainloop(struct anyconnect_info *vpninfo, int *timeout)
goto handle_outgoing;
}

/* DPD is bidirectional -- PKT 3 out, PKT 4 back */
if (vpninfo->ssl_times.dpd) {
time_t now = time(NULL);
time_t due = vpninfo->ssl_times.last_rx + vpninfo->ssl_times.dpd;
time_t overdue = vpninfo->ssl_times.last_rx + (2 * vpninfo->ssl_times.dpd);

/* If we already have DPD outstanding, don't flood */
if (vpninfo->ssl_times.last_dpd > vpninfo->ssl_times.last_rx) {
if (verbose) {
printf("DTLS DPD outstanding. Will kill in %ld seconds\n",
overdue - now);
}
due = vpninfo->ssl_times.last_dpd + vpninfo->ssl_times.dpd;
}
if (now > overdue) {
fprintf(stderr, "SSL Dead Peer Detection detected dead peer!\n");
vpninfo->quit_reason = "SSL DPD detected dead peer";
/* FIXME: We should try to reconnect with the same cookie */
return 1;
}

if (now >= due) {
static unsigned char cstp_dpd[8] =
{'S', 'T', 'F', 1, 0, 0, 3, 0};
/* Haven't heard anything from the other end for a while.
Check if it's still there */
/* FIXME: If isn't, we should act on that */
SSL_write(vpninfo->https_ssl, cstp_dpd, 8);
vpninfo->ssl_times.last_dpd = vpninfo->ssl_times.last_tx = now;

due = now + vpninfo->ssl_times.dpd;
if (verbose)
printf("Sent SSL DPD\n");
}

if (verbose && due < overdue)
printf("Next SSL DPD due in %ld seconds\n", (due - now));
if (*timeout > (due - now) * 1000)
*timeout = (due - now) * 1000;
}

/* Keepalive is just client -> server */
if (vpninfo->ssl_times.keepalive) {
time_t now = time(NULL);
time_t due = vpninfo->ssl_times.last_tx + vpninfo->ssl_times.keepalive;

if (now >= due) {
static unsigned char cstp_keepalive[8] =
{'S', 'T', 'F', 1, 0, 0, 7, 0};

/* Send something (which is discarded), to keep
the connection alive. */
SSL_write(vpninfo->https_ssl, cstp_keepalive, 8);
vpninfo->ssl_times.last_tx = now;

due = now + vpninfo->ssl_times.keepalive;
if (verbose)
printf("Sent SSL Keepalive\n");
}

if (verbose)
printf("Next SSL Keepalive due in %ld seconds\n", (due - now));
if (*timeout > (due - now) * 1000)
*timeout = (due - now) * 1000;
}

/* Work is not done if we just got rid of packets off the queue */
return work_done;
}
Expand Down

0 comments on commit 9563070

Please sign in to comment.