mirror of https://github.com/OpenIPC/firmware.git
				
				
				
			
		
			
				
	
	
		
			124 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Diff
		
	
	
			
		
		
	
	
			124 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Diff
		
	
	
| diff -drupN a/net/ipv4/tcp.c b/net/ipv4/tcp.c
 | |
| --- a/net/ipv4/tcp.c	2018-08-06 17:23:04.000000000 +0300
 | |
| +++ b/net/ipv4/tcp.c	2022-06-12 05:28:14.000000000 +0300
 | |
| @@ -538,6 +538,12 @@ unsigned int tcp_poll(struct file *file,
 | |
|  
 | |
|  		if (tp->urg_data & TCP_URG_VALID)
 | |
|  			mask |= POLLPRI;
 | |
| +	} else if (state == TCP_SYN_SENT && inet_sk(sk)->defer_connect) {
 | |
| +		/* Active TCP fastopen socket with defer_connect
 | |
| +		 * Return POLLOUT so application can call write()
 | |
| +		 * in order for kernel to generate SYN+data
 | |
| +		 */
 | |
| +		mask |= POLLOUT | POLLWRNORM;
 | |
|  	}
 | |
|  	/* This barrier is coupled with smp_wmb() in tcp_reset() */
 | |
|  	smp_rmb();
 | |
| @@ -1079,6 +1085,7 @@ static int tcp_sendmsg_fastopen(struct s
 | |
|  				int *copied, size_t size)
 | |
|  {
 | |
|  	struct tcp_sock *tp = tcp_sk(sk);
 | |
| +	struct inet_sock *inet = inet_sk(sk);
 | |
|  	struct sockaddr *uaddr = msg->msg_name;
 | |
|  	int err, flags;
 | |
|  
 | |
| @@ -1096,11 +1103,26 @@ static int tcp_sendmsg_fastopen(struct s
 | |
|  	tp->fastopen_req->data = msg;
 | |
|  	tp->fastopen_req->size = size;
 | |
|  
 | |
| +	if (inet->defer_connect) {
 | |
| +		err = tcp_connect(sk);
 | |
| +		/* Same failure procedure as in tcp_v4/6_connect */
 | |
| +		if (err) {
 | |
| +			tcp_set_state(sk, TCP_CLOSE);
 | |
| +			inet->inet_dport = 0;
 | |
| +			sk->sk_route_caps = 0;
 | |
| +		}
 | |
| +	}
 | |
|  	flags = (msg->msg_flags & MSG_DONTWAIT) ? O_NONBLOCK : 0;
 | |
|  	err = __inet_stream_connect(sk->sk_socket, uaddr,
 | |
|  				    msg->msg_namelen, flags);
 | |
| -	*copied = tp->fastopen_req->copied;
 | |
| -	tcp_free_fastopen_req(tp);
 | |
| +	/* fastopen_req could already be freed in __inet_stream_connect
 | |
| +	 * if the connection times out or gets rst
 | |
| +	 */
 | |
| +	if (tp->fastopen_req) {
 | |
| +		*copied = tp->fastopen_req->copied;
 | |
| +		tcp_free_fastopen_req(tp);
 | |
| +		inet->defer_connect = 0;
 | |
| +	}
 | |
|  	return err;
 | |
|  }
 | |
|  
 | |
| @@ -1118,7 +1140,7 @@ int tcp_sendmsg(struct sock *sk, struct
 | |
|  	lock_sock(sk);
 | |
|  
 | |
|  	flags = msg->msg_flags;
 | |
| -	if ((flags & MSG_FASTOPEN) && !tp->repair) {
 | |
| +	if (unlikely(flags & MSG_FASTOPEN || inet_sk(sk)->defer_connect)) {
 | |
|  		err = tcp_sendmsg_fastopen(sk, msg, &copied_syn, size);
 | |
|  		if (err == -EINPROGRESS && copied_syn > 0)
 | |
|  			goto out;
 | |
| @@ -2300,7 +2322,6 @@ int tcp_disconnect(struct sock *sk, int
 | |
|  	tp->snd_cwnd_cnt = 0;
 | |
|  	tp->window_clamp = 0;
 | |
|  	tcp_set_ca_state(sk, TCP_CA_Open);
 | |
| -	tp->is_sack_reneg = 0;
 | |
|  	tcp_clear_retrans(tp);
 | |
|  	inet_csk_delack_init(sk);
 | |
|  	/* Initialize rcv_mss to TCP_MIN_MSS to avoid division by 0
 | |
| @@ -2314,6 +2335,10 @@ int tcp_disconnect(struct sock *sk, int
 | |
|  	sk->sk_rx_dst = NULL;
 | |
|  	tcp_saved_syn_free(tp);
 | |
|  
 | |
| +	/* Clean up fastopen related fields */
 | |
| +	tcp_free_fastopen_req(tp);
 | |
| +	inet->defer_connect = 0;
 | |
| +
 | |
|  	WARN_ON(inet->inet_num && !icsk->icsk_bind_hash);
 | |
|  
 | |
|  	if (sk->sk_frag.page) {
 | |
| @@ -2688,6 +2713,18 @@ static int do_tcp_setsockopt(struct sock
 | |
|  			err = -EINVAL;
 | |
|  		}
 | |
|  		break;
 | |
| +	case TCP_FASTOPEN_CONNECT:
 | |
| +		if (val > 1 || val < 0) {
 | |
| +			err = -EINVAL;
 | |
| +		} else if (sysctl_tcp_fastopen & TFO_CLIENT_ENABLE) {
 | |
| +			if (sk->sk_state == TCP_CLOSE)
 | |
| +				tp->fastopen_connect = val;
 | |
| +			else
 | |
| +				err = -EINVAL;
 | |
| +		} else {
 | |
| +			err = -EOPNOTSUPP;
 | |
| +		}
 | |
| +		break;
 | |
|  	case TCP_TIMESTAMP:
 | |
|  		if (!tp->repair)
 | |
|  			err = -EPERM;
 | |
| @@ -3001,6 +3038,10 @@ static int do_tcp_getsockopt(struct sock
 | |
|  		val = icsk->icsk_accept_queue.fastopenq.max_qlen;
 | |
|  		break;
 | |
|  
 | |
| +	case TCP_FASTOPEN_CONNECT:
 | |
| +		val = tp->fastopen_connect;
 | |
| +		break;
 | |
| +
 | |
|  	case TCP_TIMESTAMP:
 | |
|  		val = tcp_time_stamp + tp->tsoffset;
 | |
|  		break;
 | |
| @@ -3276,7 +3317,11 @@ EXPORT_SYMBOL_GPL(tcp_abort);
 | |
|  
 | |
|  extern struct tcp_congestion_ops tcp_reno;
 | |
|  
 | |
| +#ifdef CONFIG_BASE_SMALL
 | |
| +static __initdata unsigned long thash_entries = 16;
 | |
| +#else
 | |
|  static __initdata unsigned long thash_entries;
 | |
| +#endif
 | |
|  static int __init set_thash_entries(char *str)
 | |
|  {
 | |
|  	ssize_t ret;
 |