Unverified Commit 979b012e authored by Alessandro Ghedini's avatar Alessandro Ghedini Committed by Daniel Stenberg
Browse files

connect: add support for new TCP Fast Open API on Linux

The new API added in Linux 4.11 only requires setting a socket option
before connecting, without the whole sento() machinery.

Notably, this makes it possible to use TFO with SSL connections on Linux
as well, without the need to mess around with OpenSSL (or whatever other
SSL library) internals.

Closes #2056
parent 9f691be3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3275,6 +3275,7 @@ AC_CHECK_HEADERS(
        net/if.h \
        netinet/in.h \
        sys/un.h \
        linux/tcp.h \
        netinet/tcp.h \
        netdb.h \
        sys/sockio.h \
+16 −3
Original line number Diff line number Diff line
@@ -28,8 +28,10 @@
#ifdef HAVE_SYS_UN_H
#include <sys/un.h> /* for sockaddr_un */
#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h> /* for TCP_NODELAY */
#ifdef HAVE_LINUX_TCP_H
#include <linux/tcp.h>
#elif defined(HAVE_NETINET_TCP_H)
#include <netinet/tcp.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
@@ -989,6 +991,9 @@ static CURLcode singleipconnect(struct connectdata *conn,
  char ipaddress[MAX_IPADR_LEN];
  long port;
  bool is_tcp;
#ifdef TCP_FASTOPEN_CONNECT
  int optval = 1;
#endif

  *sockp = CURL_SOCKET_BAD;

@@ -1092,7 +1097,15 @@ static CURLcode singleipconnect(struct connectdata *conn,
#  else
      rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
#  endif /* HAVE_BUILTIN_AVAILABLE */
#elif defined(MSG_FASTOPEN) /* Linux */
#elif defined(TCP_FASTOPEN_CONNECT) /* Linux >= 4.11 */
      if(setsockopt(sockfd, IPPROTO_TCP, TCP_FASTOPEN_CONNECT,
                    (void *)&optval, sizeof(optval)) < 0)
        infof(data, "Failed to enable TCP Fast Open on fd %d\n", sockfd);
      else
        infof(data, "TCP_FASTOPEN_CONNECT set\n");

      rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
#elif defined(MSG_FASTOPEN) /* old Linux */
      if(conn->given->flags & PROTOPT_SSL)
        rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
      else
+5 −1
Original line number Diff line number Diff line
@@ -22,6 +22,10 @@

#include "curl_setup.h"

#ifdef HAVE_LINUX_TCP_H
#include <linux/tcp.h>
#endif

#include <curl/curl.h>

#include "urldata.h"
@@ -360,7 +364,7 @@ ssize_t Curl_send_plain(struct connectdata *conn, int num,
     available. */
  pre_receive_plain(conn, num);

#ifdef MSG_FASTOPEN /* Linux */
#if defined(MSG_FASTOPEN) && !defined(TCP_FASTOPEN_CONNECT) /* Linux */
  if(conn->bits.tcp_fastopen) {
    bytes_written = sendto(sockfd, mem, len, MSG_FASTOPEN,
                           conn->ip_addr->ai_addr, conn->ip_addr->ai_addrlen);
+6 −1
Original line number Diff line number Diff line
@@ -26,6 +26,10 @@
#include <limits.h>
#endif

#ifdef HAVE_LINUX_TCP_H
#include <linux/tcp.h>
#endif

#include "urldata.h"
#include "url.h"
#include "progress.h"
@@ -2450,7 +2454,8 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option,
    data->set.tcp_keepintvl = arg;
    break;
  case CURLOPT_TCP_FASTOPEN:
#if defined(CONNECT_DATA_IDEMPOTENT) || defined(MSG_FASTOPEN)
#if defined(CONNECT_DATA_IDEMPOTENT) || defined(MSG_FASTOPEN) || \
   defined(TCP_FASTOPEN_CONNECT)
    data->set.tcp_fastopen = (0 != va_arg(param, long))?TRUE:FALSE;
#else
    result = CURLE_NOT_BUILT_IN;