Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf60af03 authored by Yuchung Cheng's avatar Yuchung Cheng Committed by David S. Miller
Browse files

net-tcp: Fast Open client - sendmsg(MSG_FASTOPEN)



sendmsg() (or sendto()) with MSG_FASTOPEN is a combo of connect(2)
and write(2). The application should replace connect() with it to
send data in the opening SYN packet.

For blocking socket, sendmsg() blocks until all the data are buffered
locally and the handshake is completed like connect() call. It
returns similar errno like connect() if the TCP handshake fails.

For non-blocking socket, it returns the number of bytes queued (and
transmitted in the SYN-data packet) if cookie is available. If cookie
is not available, it transmits a data-less SYN packet with Fast Open
cookie request option and returns -EINPROGRESS like connect().

Using MSG_FASTOPEN on connecting or connected socket will result in
simlar errno like repeating connect() calls. Therefore the application
should only use this flag on new sockets.

The buffer size of sendmsg() is independent of the MSS of the connection.

Signed-off-by: default avatarYuchung Cheng <ycheng@google.com>
Acked-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8e4178c1
Loading
Loading
Loading
Loading
+11 −0
Original line number Original line Diff line number Diff line
@@ -468,6 +468,17 @@ tcp_syncookies - BOOLEAN
	SYN flood warnings in logs not being really flooded, your server
	SYN flood warnings in logs not being really flooded, your server
	is seriously misconfigured.
	is seriously misconfigured.


tcp_fastopen - INTEGER
	Enable TCP Fast Open feature (draft-ietf-tcpm-fastopen) to send data
	in the opening SYN packet. To use this feature, the client application
	must not use connect(). Instead, it should use sendmsg() or sendto()
	with MSG_FASTOPEN flag which performs a TCP handshake automatically.

	The values (bitmap) are:
	1: Enables sending data in the opening SYN on the client

	Default: 0

tcp_syn_retries - INTEGER
tcp_syn_retries - INTEGER
	Number of times initial SYNs for an active TCP connection attempt
	Number of times initial SYNs for an active TCP connection attempt
	will be retransmitted. Should not be higher than 255. Default value
	will be retransmitted. Should not be higher than 255. Default value
+1 −0
Original line number Original line Diff line number Diff line
@@ -268,6 +268,7 @@ struct ucred {
#define MSG_SENDPAGE_NOTLAST 0x20000 /* sendpage() internal : not the last page */
#define MSG_SENDPAGE_NOTLAST 0x20000 /* sendpage() internal : not the last page */
#define MSG_EOF         MSG_FIN
#define MSG_EOF         MSG_FIN


#define MSG_FASTOPEN	0x20000000	/* Send data in TCP SYN */
#define MSG_CMSG_CLOEXEC 0x40000000	/* Set close_on_exit for file
#define MSG_CMSG_CLOEXEC 0x40000000	/* Set close_on_exit for file
					   descriptor received through
					   descriptor received through
					   SCM_RIGHTS */
					   SCM_RIGHTS */
+4 −2
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@ struct socket;
extern int inet_release(struct socket *sock);
extern int inet_release(struct socket *sock);
extern int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
extern int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
			       int addr_len, int flags);
			       int addr_len, int flags);
extern int __inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
				 int addr_len, int flags);
extern int inet_dgram_connect(struct socket *sock, struct sockaddr *uaddr,
extern int inet_dgram_connect(struct socket *sock, struct sockaddr *uaddr,
			      int addr_len, int flags);
			      int addr_len, int flags);
extern int inet_accept(struct socket *sock, struct socket *newsock, int flags);
extern int inet_accept(struct socket *sock, struct socket *newsock, int flags);
+3 −0
Original line number Original line Diff line number Diff line
@@ -212,6 +212,9 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo);
/* TCP initial congestion window as per draft-hkchu-tcpm-initcwnd-01 */
/* TCP initial congestion window as per draft-hkchu-tcpm-initcwnd-01 */
#define TCP_INIT_CWND		10
#define TCP_INIT_CWND		10


/* Bit Flags for sysctl_tcp_fastopen */
#define	TFO_CLIENT_ENABLE	1

extern struct inet_timewait_death_row tcp_death_row;
extern struct inet_timewait_death_row tcp_death_row;


/* sysctl variables for tcp */
/* sysctl variables for tcp */
+14 −5
Original line number Original line Diff line number Diff line
@@ -585,7 +585,7 @@ static long inet_wait_for_connect(struct sock *sk, long timeo, int writebias)
 *	Connect to a remote host. There is regrettably still a little
 *	Connect to a remote host. There is regrettably still a little
 *	TCP 'magic' in here.
 *	TCP 'magic' in here.
 */
 */
int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
int __inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
			  int addr_len, int flags)
			  int addr_len, int flags)
{
{
	struct sock *sk = sock->sk;
	struct sock *sk = sock->sk;
@@ -595,8 +595,6 @@ int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
	if (addr_len < sizeof(uaddr->sa_family))
	if (addr_len < sizeof(uaddr->sa_family))
		return -EINVAL;
		return -EINVAL;


	lock_sock(sk);

	if (uaddr->sa_family == AF_UNSPEC) {
	if (uaddr->sa_family == AF_UNSPEC) {
		err = sk->sk_prot->disconnect(sk, flags);
		err = sk->sk_prot->disconnect(sk, flags);
		sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED;
		sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED;
@@ -663,7 +661,6 @@ int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
	sock->state = SS_CONNECTED;
	sock->state = SS_CONNECTED;
	err = 0;
	err = 0;
out:
out:
	release_sock(sk);
	return err;
	return err;


sock_error:
sock_error:
@@ -673,6 +670,18 @@ int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
		sock->state = SS_DISCONNECTING;
		sock->state = SS_DISCONNECTING;
	goto out;
	goto out;
}
}
EXPORT_SYMBOL(__inet_stream_connect);

int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
			int addr_len, int flags)
{
	int err;

	lock_sock(sock->sk);
	err = __inet_stream_connect(sock, uaddr, addr_len, flags);
	release_sock(sock->sk);
	return err;
}
EXPORT_SYMBOL(inet_stream_connect);
EXPORT_SYMBOL(inet_stream_connect);


/*
/*
Loading