Skip to content

Commit

Permalink
Reduce unnecessary connection-rebuilding for Juniper
Browse files Browse the repository at this point in the history
The current oNCP (Juniper) protocol support sets "Connection: close" in all
HTTP requests.  This is not ideal because it requires many TLS handshakes
and round-trips, making the connection very slow to start when the latency
of the connection to the gateway is high, especially if the number of
authentication forms and redirects is large.

Simply removing the "Connection: close" header causes the oNCP connection
to fail; the server doesn't interpret the first packet sent over the oNCP
tunnel correctly (the vestigial authentication packet).

However, it appears that the "Connection: close" header *only* needs to be
specified for this final HTTP request, and not for any of the prior ones.
The presence of this header seems to signal to the gateway that it should
stop treating this as an HTTP connection, and start treating it as an
oNCP tunnel.

Tested on two different Juniper gateways, one which returns
"NCP-Version: 2" and one which returns "NCP-Version: 3" in response to
the oNCP negotiation requests.
  • Loading branch information
dlenski committed Aug 2, 2018
1 parent ffebb56 commit 46de5ee
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 1 deletion.
1 change: 0 additions & 1 deletion auth-juniper.c
Expand Up @@ -47,7 +47,6 @@ void oncp_common_headers(struct openconnect_info *vpninfo, struct oc_text_buf *b
{
http_common_headers(vpninfo, buf);

buf_append(buf, "Connection: close\r\n");
// buf_append(buf, "Content-Length: 256\r\n");
buf_append(buf, "NCP-Version: 3\r\n");
// buf_append(buf, "Accept-Encoding: gzip\r\n");
Expand Down
14 changes: 14 additions & 0 deletions oncp.c
Expand Up @@ -561,6 +561,11 @@ int oncp_connect(struct openconnect_info *vpninfo)
reqbuf = buf_alloc();

buf_append(reqbuf, "POST /dana/js?prot=1&svc=1 HTTP/1.1\r\n");
/* Seems unnecessary because we always ignore the response body,
and close the connection anyway, but retained in case any
server depends on it. (See comments on second negotiation
request below. */
buf_append(reqbuf, "Connection: close\r\n");
oncp_common_headers(vpninfo, reqbuf);
buf_append(reqbuf, "Content-Length: 256\r\n");
buf_append(reqbuf, "\r\n");
Expand All @@ -572,6 +577,7 @@ int oncp_connect(struct openconnect_info *vpninfo)
goto out;
}

vpn_progress(vpninfo, PRG_TRACE, _("Sending oNCP negotiation request #1\n"));
ret = vpninfo->ssl_write(vpninfo, reqbuf->data, reqbuf->pos);
if (ret < 0)
goto out;
Expand Down Expand Up @@ -606,6 +612,13 @@ int oncp_connect(struct openconnect_info *vpninfo)

buf_truncate(reqbuf);
buf_append(reqbuf, "POST /dana/js?prot=1&svc=4 HTTP/1.1\r\n");
/* The TLS socket actually remains open for use by the oNCP
tunnel, but the "Connection: close" header is nevertheless
required here. It appears to signal to the server to stop
treating this as an HTTP connection and to start treating
it as an oNCP connection.
*/
buf_append(reqbuf, "Connection: close\r\n");
oncp_common_headers(vpninfo, reqbuf);
buf_append(reqbuf, "Content-Length: 256\r\n");
buf_append(reqbuf, "\r\n");
Expand All @@ -616,6 +629,7 @@ int oncp_connect(struct openconnect_info *vpninfo)
ret = buf_error(reqbuf);
goto out;
}
vpn_progress(vpninfo, PRG_TRACE, _("Sending oNCP negotiation request #2\n"));
ret = vpninfo->ssl_write(vpninfo, reqbuf->data, reqbuf->pos);
if (ret < 0)
goto out;
Expand Down

0 comments on commit 46de5ee

Please sign in to comment.