This set of patches will bring “Fast Open” Option support to MPTCP in linux kernel. The aim of Fast Open Mechanism is to eliminate one round trip time from a MPTCP conversation by allowing data to be included as part of the SYN segment that initiates the connection.
IETF RFC 8684: Appendix B. TCP Fast Open and MPTCP. IETF RFC LINK
These new patches (LWN | ML: mptcp.lists.linux.dev) provide the full support of TFO with MPTCP,
which means:
– MSG_FASTOPEN sendmsg flag support (patch 1/8)
– TFO support for the listener side (patches 2, 3, 4, 5/8)
– TCP_FASTOPEN socket option (patch 6/8)
– TCP_FASTOPEN_KEY socket option (patch 7/8)
– SELFTESTS (patch 8/8)
2 methods to Request a cookie (in MPTCP) are currently exist:
1) Listener side + Initator side with: MSG_FASTOPEN
LWN publication: https://lwn.net/Articles/916023/
2) Initiator side with: TCP_FASTOPEN_CONNECT
LWN publication https://lwn.net/Articles/909590/
Code examples for initiator side:
MSG_FASTOPEN (Updated on 6 Nov. 2022)
Here is example of Initiator in userspace program written in C
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/tcp.h>
#include <string.h>
#include <signal.h>
#define SERVER_PORT 7003
#define MAXLINE 999
int main(int argc, char *argv[])
{
char sendline[MAXLINE + 1], recvline[MAXLINE + 1];
char *fileLocation = "./fileToDownload";
char *serverAddress = "10.10.0.2:1234"
int sock_fd = -1;
int ret;
/* Generate HTTP GET into variable sendline*/
snprintf(sendline, 999,
"GET %s HTTP/1.0\r\n"
"Host: %s\r\n"
"Content-type: application/x-www-form-urlencoded\r\n"
"Content-length: %d\r\n\r\n"
"%s\r\n", fileLocation, serverAddress , (unsigned int)strlen(""), "");
struct sockaddr_in daddr;
memset(&daddr,0,sizeof(daddr));
inet_pton(AF_INET, "10.10.0.2", &daddr.sin_addr);
daddr.sin_family = AF_INET;
daddr.sin_port = htons(SERVER_PORT);
/* set the mprotocol MPTCP */
sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP);
/* set the MSG_FASTOPEN */
ret = sendto(sock_fd, sendline, strlen(sendline), MSG_FASTOPEN,(struct sockaddr *) &daddr, sizeof(daddr));
printf ("info: %d \n", ret);
close(sock_fd);
return EXIT_SUCCESS;
}
PacketDrill test: Link to Github
PacketDrill test result: Link to Github
Here is example of Initiator in userspace program written in C:
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/tcp.h>
#include <string.h>
#include <signal.h>
#define SERVER_PORT 7003
#define MAXLINE 999
int main(int argc, char *argv[])
{
char sendline[MAXLINE + 1], recvline[MAXLINE + 1];
struct sockaddr_in daddr;
int sock_fd = -1;
int enable = 1;
int ret;
snprintf(sendline, 999,
"GET %s HTTP/1.0\r\n" // POST or GET, both tested and works. Both HTTP 1.0 HTTP 1.1 works, but sometimes
"Host: %s\r\n" // but sometimes HTTP 1.0 works better in localhost type
"Content-type: application/x-www-form-urlencoded\r\n"
"Content-length: %d\r\n\r\n"
"%s\r\n", "/prepare2.sh", "6.6.6.6:666" , (unsigned int)strlen(""), "")
memset(&daddr,0,sizeof(daddr));
inet_pton(AF_INET, "6.6.6.6", &daddr.sin_addr);
daddr.sin_family = AF_INET;
daddr.sin_port = htons(SERVER_PORT);
/* set the mprotocol MPTCP */
sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP);
/* set the TCP_FASTOPEN_CONNECT */
setsockopt(sock_fd, SOL_TCP, TCP_FASTOPEN_CONNECT, &enable, sizeof(enable));
connect(sock_fd, (struct sockaddr *) &daddr, sizeof(daddr));
ret = sendto(sock_fd, sendline, strlen(sendline), 0,(struct sockaddr *) &daddr, sizeof(daddr));
printf ("info: %d \n", ret);
close(sock_fd);
return EXIT_SUCCESS;
}
Environment configuration (linux) for TCP_FASTOPEN:
sudo modprobe veth
sudo ip netns add server
sudo ip netns add client
sudo ip link add veth0 type veth peer name veth1
sudo ip link set veth1 netns server
sudo ip link set veth0 netns client
sudo ip netns exec client ip a a 10.10.0.1/24 dev veth0
sudo ip netns exec server ip a a 10.10.0.2/24 dev veth1
sudo ip netns exec client ip link set dev veth0 up
sudo ip netns exec server ip link set dev veth1 up
sudo ip netns exec server bash -c "echo 3 > /proc/sys/net/ipv4/tcp_fastopen"
sudo ip netns exec client bash -c "echo 3 > /proc/sys/net/ipv4/tcp_fastopen"
Thank you for reading.