if (ret < 0)
goto out;
- ret = process_http_response(vpninfo, 1, NULL, reqbuf);
- if (ret < 0)
- goto out;
-
- if (ret != 201 && ret != 200) {
- vpn_progress(vpninfo, PRG_ERR,
- _("Unexpected %d result from server\n"),
- ret);
- ret = -EINVAL;
- goto out;
- }
+ /* XX: If this connection request succeeds, no HTTP response appears.
+ * We just start sending our encapsulated PPP configuration packets.
+ * However, if the request FAILS, it WILL send an HTTP response.
+ * We handle that in the PPP mainloop.
+ *
+ * Don't blame me. I didn't design this.
+ */
ret = openconnect_ppp_new(vpninfo, PPP_ENCAP_FORTINET_HDLC, ipv4, ipv6);
ppp->encap_len = 4;
break;
+ case PPP_ENCAP_FORTINET_HDLC:
+ ppp->check_http_response = 1;
+ /* fall through */
+
case PPP_ENCAP_F5_HDLC:
/* XX: F5 server cancels our IP address allocation if we PPP-terminate */
ppp->no_terminate_on_pause = 1;
/* fall through */
case PPP_ENCAP_RFC1662_HDLC:
- case PPP_ENCAP_FORTINET_HDLC:
ppp->encap_len = 0;
ppp->hdlc = 1;
break;
if (len < 0)
goto do_reconnect;
+ /* XX: Some protocols require us to check for an HTTP response in place
+ * of the first packet
+ */
+ if (ppp->check_http_response) {
+ ppp->check_http_response = 0;
+ if (!memcmp(eh, "HTTP/", 5)) {
+ const char *sol = (const char *)eh;
+ const char *eol = memchr(sol, '\r', len) ?: memchr(sol, '\n', len);
+ if (eol)
+ len = eol - sol;
+ vpn_progress(vpninfo, PRG_ERR,
+ _("Got unexpected HTTP response: %.*s\n"), len, sol);
+ vpninfo->quit_reason = "Received HTTP response (not a PPP packet)";
+ return -EINVAL;
+ }
+ }
+
next_pkt:
/* At this point:
* eh: pointer to start of bytes-from-the-wire