]> granicus.if.org Git - curl/commitdiff
connect: implement TCP Fast Open for Linux
authorAlessandro Ghedini <alessandro@ghedini.me>
Sun, 3 Apr 2016 12:08:28 +0000 (13:08 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 18 Apr 2016 21:21:50 +0000 (23:21 +0200)
Closes #660

docs/libcurl/opts/CURLOPT_TCP_FASTOPEN.3
lib/connect.c
lib/sendf.c
lib/url.c

index 6f6ddba728af876925dff0f33dcf3579d86c8768..f8f9343849da2e32bda9c5307b3d6cdeb16463dc 100644 (file)
@@ -40,7 +40,8 @@ All
 .SH EXAMPLE
 TODO
 .SH AVAILABILITY
-Added in 7.49.0. This option is currently only supported on OS X El Capitan.
+Added in 7.49.0. This option is currently only supported on Linux and  OS X
+El Capitan.
 .SH RETURN VALUE
 Returns CURLE_OK if fast open is supported by the operating system, otherwise
 returns CURLE_NOT_BUILT_IN.
index a4eb56d00bdf5bff3f1b7606ec8874bafe2e2dd8..bfc22992c34790938c1821168d18790ced706ec0 100644 (file)
@@ -668,7 +668,7 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
     /* there's no connection! */
     return;
 
-  if(!conn->bits.reuse) {
+  if(!conn->bits.reuse && !conn->bits.tcp_fastopen) {
     int error;
 
     len = sizeof(struct Curl_sockaddr_storage);
@@ -776,7 +776,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
         trynextip(conn, sockindex, 1);
       }
     }
-    else if(rc == CURL_CSELECT_OUT) {
+    else if(rc == CURL_CSELECT_OUT || conn->bits.tcp_fastopen) {
       if(verifyconnect(conn->tempsock[i], &error)) {
         /* we are connected with TCP, awesome! */
 
@@ -1109,6 +1109,8 @@ static CURLcode singleipconnect(struct connectdata *conn,
       rc = connectx(sockfd, &endpoints, SAE_ASSOCID_ANY,
                     CONNECT_RESUME_ON_READ_WRITE | CONNECT_DATA_IDEMPOTENT,
                     NULL, 0, NULL, NULL);
+#elif defined(MSG_FASTOPEN) /* Linux */
+      rc = 0; /* Do nothing */
 #endif
     }
     else {
index ea04ae83e93bf19fe89a6fe8ecb7869d13d42a83..a75c5c743c0fcd1b603177c6a508a63fefbf6466 100644 (file)
@@ -254,7 +254,17 @@ ssize_t Curl_send_plain(struct connectdata *conn, int num,
                         const void *mem, size_t len, CURLcode *code)
 {
   curl_socket_t sockfd = conn->sock[num];
-  ssize_t bytes_written = swrite(sockfd, mem, len);
+  ssize_t bytes_written;
+
+#ifdef MSG_FASTOPEN /* Linux */
+  if(conn->bits.tcp_fastopen) {
+    bytes_written = sendto(sockfd, mem, len, MSG_FASTOPEN,
+                           conn->ip_addr->ai_addr, conn->ip_addr->ai_addrlen);
+    conn->bits.tcp_fastopen = FALSE;
+  }
+  else
+#endif
+    bytes_written = swrite(sockfd, mem, len);
 
   *code = CURLE_OK;
   if(-1 == bytes_written) {
@@ -268,7 +278,8 @@ ssize_t Curl_send_plain(struct connectdata *conn, int num,
       /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
          due to its inability to send off data without blocking. We therefor
          treat both error codes the same here */
-      (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
+      (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err) ||
+      (EINPROGRESS == err)
 #endif
       ) {
       /* this is just a case of EWOULDBLOCK */
index e76d4e8e0990b6d0b55471ee4e02854ea507c7c3..f1028f34cd2b4ba7f677329b24629e20f7840645 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -2633,7 +2633,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
     data->set.tcp_keepintvl = va_arg(param, long);
     break;
   case CURLOPT_TCP_FASTOPEN:
-#if defined(CONNECT_DATA_IDEMPOTENT)
+#if defined(CONNECT_DATA_IDEMPOTENT) || defined(MSG_FASTOPEN)
     data->set.tcp_fastopen = (0 != va_arg(param, long))?TRUE:FALSE;
 #else
     result = CURLE_NOT_BUILT_IN;