|  | 
| 16 | 16 | #include <errno.h> | 
| 17 | 17 | #include <fcntl.h> | 
| 18 | 18 | 
 | 
| 19 |  | -// Try to use TCP Fast Open to send data | 
| 20 |  | -static const char* tryTcpFastOpen(FFNetworkingState* state) | 
|  | 19 | +static const char* tryNonThreadingFastPath(FFNetworkingState* state) | 
| 21 | 20 | { | 
| 22 |  | -    if (!state->tfo) | 
| 23 |  | -    { | 
| 24 |  | -        #ifndef __APPLE__ | 
| 25 |  | -        FF_DEBUG("TCP Fast Open disabled, skipping"); | 
| 26 |  | -        return "TCP Fast Open disabled"; | 
| 27 |  | -        #else | 
| 28 |  | -        FF_DEBUG("TCP Fast Open disabled, using connectx() to send data"); | 
| 29 |  | -        #endif | 
| 30 |  | -    } | 
| 31 |  | - | 
| 32 |  | -    #if (!defined(__APPLE__) && !defined(TCP_FASTOPEN)) || (defined(__linux__) && !defined(MSG_FASTOPEN)) | 
| 33 |  | -        FF_DEBUG("TCP Fast Open not supported on this system"); | 
| 34 |  | -        FF_UNUSED(state); | 
| 35 |  | -        return "TCP Fast Open not supported"; | 
| 36 |  | -    #else | 
| 37 |  | -        FF_DEBUG("Attempting to use TCP Fast Open to connect"); | 
|  | 21 | +    #if defined(TCP_FASTOPEN) || __APPLE__ | 
| 38 | 22 | 
 | 
| 39 |  | -        #ifndef __APPLE__ // On macOS, TCP_FASTOPEN doesn't seem to be needed | 
| 40 |  | -        // Set TCP Fast Open | 
| 41 |  | -        #ifdef __linux__ | 
| 42 |  | -        int flag = 5; // the queue length of pending packets | 
| 43 |  | -        #else | 
| 44 |  | -        int flag = 1; // enable TCP Fast Open | 
| 45 |  | -        #endif | 
| 46 |  | -        if (setsockopt(state->sockfd, IPPROTO_TCP, | 
| 47 |  | -            #ifdef __APPLE__ | 
| 48 |  | -            // https://github.com/rust-lang/libc/pull/3135 | 
| 49 |  | -            0x218 // TCP_FASTOPEN_FORCE_ENABLE | 
| 50 |  | -            #else | 
| 51 |  | -            TCP_FASTOPEN | 
|  | 23 | +        if (!state->tfo) | 
|  | 24 | +        { | 
|  | 25 | +            #ifdef __linux__ | 
|  | 26 | +            // Linux doesn't support sendto() on unconnected sockets | 
|  | 27 | +            FF_DEBUG("TCP Fast Open disabled, skipping"); | 
|  | 28 | +            return "TCP Fast Open disabled"; | 
| 52 | 29 |             #endif | 
| 53 |  | -            , &flag, sizeof(flag)) != 0) { | 
| 54 |  | -            FF_DEBUG("Failed to set TCP_FASTOPEN option: %s", strerror(errno)); | 
| 55 |  | -            return "setsockopt(TCP_FASTOPEN) failed"; | 
| 56 |  | -        } else { | 
|  | 30 | +        } | 
|  | 31 | +        else | 
|  | 32 | +        { | 
|  | 33 | +            FF_DEBUG("Attempting to use TCP Fast Open to connect"); | 
|  | 34 | + | 
|  | 35 | +            #ifndef __APPLE__ // On macOS, TCP_FASTOPEN doesn't seem to be needed | 
|  | 36 | +            // Set TCP Fast Open | 
| 57 | 37 |             #ifdef __linux__ | 
| 58 |  | -            FF_DEBUG("Successfully set TCP_FASTOPEN option, queue length: %d", flag); | 
| 59 |  | -            #elif defined(__APPLE__) | 
| 60 |  | -            FF_DEBUG("Successfully set TCP_FASTOPEN_FORCE_ENABLE option"); | 
|  | 38 | +            int flag = 5; // the queue length of pending packets | 
| 61 | 39 |             #else | 
| 62 |  | -            FF_DEBUG("Successfully set TCP_FASTOPEN option"); | 
|  | 40 | +            int flag = 1; // enable TCP Fast Open | 
|  | 41 | +            #endif | 
|  | 42 | +            if (setsockopt(state->sockfd, IPPROTO_TCP, | 
|  | 43 | +                #ifdef __APPLE__ | 
|  | 44 | +                // https://github.com/rust-lang/libc/pull/3135 | 
|  | 45 | +                0x218 // TCP_FASTOPEN_FORCE_ENABLE | 
|  | 46 | +                #else | 
|  | 47 | +                TCP_FASTOPEN | 
|  | 48 | +                #endif | 
|  | 49 | +                , &flag, sizeof(flag)) != 0) { | 
|  | 50 | +                FF_DEBUG("Failed to set TCP_FASTOPEN option: %s", strerror(errno)); | 
|  | 51 | +                return "setsockopt(TCP_FASTOPEN) failed"; | 
|  | 52 | +            } else { | 
|  | 53 | +                #ifdef __linux__ | 
|  | 54 | +                FF_DEBUG("Successfully set TCP_FASTOPEN option, queue length: %d", flag); | 
|  | 55 | +                #elif defined(__APPLE__) | 
|  | 56 | +                FF_DEBUG("Successfully set TCP_FASTOPEN_FORCE_ENABLE option"); | 
|  | 57 | +                #else | 
|  | 58 | +                FF_DEBUG("Successfully set TCP_FASTOPEN option"); | 
|  | 59 | +                #endif | 
|  | 60 | +            } | 
| 63 | 61 |             #endif | 
| 64 | 62 |         } | 
| 65 |  | -        #endif | 
| 66 | 63 | 
 | 
| 67 | 64 |         #ifndef __APPLE__ | 
| 68 |  | -        FF_DEBUG("Using sendto() + MSG_FASTOPEN to send %u bytes of data", state->command.length); | 
|  | 65 | +        FF_DEBUG("Using sendto() + MSG_DONTWAIT to send %u bytes of data", state->command.length); | 
| 69 | 66 |         ssize_t sent = sendto(state->sockfd, | 
| 70 |  | -                              state->command.chars, | 
| 71 |  | -                              state->command.length, | 
|  | 67 | +                                state->command.chars, | 
|  | 68 | +                                state->command.length, | 
| 72 | 69 |             #ifdef MSG_FASTOPEN | 
| 73 |  | -                              MSG_FASTOPEN | | 
|  | 70 | +                                MSG_FASTOPEN | | 
| 74 | 71 |             #endif | 
| 75 | 72 |             #ifdef MSG_NOSIGNAL | 
| 76 |  | -                              MSG_NOSIGNAL | | 
|  | 73 | +                                MSG_NOSIGNAL | | 
| 77 | 74 |             #endif | 
| 78 |  | -                              MSG_DONTWAIT, | 
| 79 |  | -                              state->addr->ai_addr, | 
| 80 |  | -                              state->addr->ai_addrlen); | 
|  | 75 | +                                MSG_DONTWAIT, | 
|  | 76 | +                                state->addr->ai_addr, | 
|  | 77 | +                                state->addr->ai_addrlen); | 
| 81 | 78 |         #else | 
| 82 | 79 |         if (fcntl(state->sockfd, F_SETFL, O_NONBLOCK) == -1) { | 
| 83 | 80 |             FF_DEBUG("fcntl(F_SETFL) failed: %s", strerror(errno)); | 
| @@ -135,6 +132,9 @@ static const char* tryTcpFastOpen(FFNetworkingState* state) | 
| 135 | 132 |         #else | 
| 136 | 133 |         return "sendto() failed"; | 
| 137 | 134 |         #endif | 
|  | 135 | +    #else | 
|  | 136 | +        FF_UNUSED(state); | 
|  | 137 | +        return "TFO support is not available"; | 
| 138 | 138 |     #endif | 
| 139 | 139 | } | 
| 140 | 140 | 
 | 
| @@ -333,12 +333,12 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho | 
| 333 | 333 |     } | 
| 334 | 334 |     FF_DEBUG("Network state initialization successful"); | 
| 335 | 335 | 
 | 
| 336 |  | -    const char* tfoResult = tryTcpFastOpen(state); | 
|  | 336 | +    const char* tfoResult = tryNonThreadingFastPath(state); | 
| 337 | 337 |     if (tfoResult == NULL) { | 
| 338 |  | -        FF_DEBUG("TryTcpFastOpen succeeded or in progress"); | 
|  | 338 | +        FF_DEBUG("TryNonThreadingFastPath() succeeded or in progress"); | 
| 339 | 339 |         return NULL; | 
| 340 | 340 |     } | 
| 341 |  | -    FF_DEBUG("TryTcpFastOpen failed: %s, trying traditional connection", tfoResult); | 
|  | 341 | +    FF_DEBUG("TryNonThreadingFastPath() failed: %s, trying traditional connection", tfoResult); | 
| 342 | 342 | 
 | 
| 343 | 343 |     #ifdef FF_HAVE_THREADS | 
| 344 | 344 |     if (instance.config.general.multithreading) | 
|  | 
0 commit comments