connect: implement TCP Fast Open for Linux

Closes #660
This commit is contained in:
Alessandro Ghedini 2016-04-03 13:08:28 +01:00 committed by Daniel Stenberg
parent d49087f6bc
commit 03de4e4b21
4 changed files with 20 additions and 6 deletions

View 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.

View 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 {

View 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 */

View File

@ -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;