tcp: constify tcp_make_synack() socket argument
listener socket is not locked when tcp_make_synack() is called. We better make sure no field is written. There is one exception : Since SYNACK packets are attached to the listener at this moment (or SYN_RECV child in case of Fast Open), sock_wmalloc() needs to update sk->sk_wmem_alloc, but this is done using atomic operations so this is safe. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
6ac705b180
commit
5d062de7f8
@ -461,7 +461,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
|
||||
int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb);
|
||||
int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len);
|
||||
int tcp_connect(struct sock *sk);
|
||||
struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
|
||||
struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
|
||||
struct request_sock *req,
|
||||
struct tcp_fastopen_cookie *foc);
|
||||
int tcp_disconnect(struct sock *sk, int flags);
|
||||
|
@ -2944,20 +2944,25 @@ int tcp_send_synack(struct sock *sk)
|
||||
* Allocate one skb and build a SYNACK packet.
|
||||
* @dst is consumed : Caller should not use it again.
|
||||
*/
|
||||
struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
|
||||
struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
|
||||
struct request_sock *req,
|
||||
struct tcp_fastopen_cookie *foc)
|
||||
{
|
||||
struct tcp_out_options opts;
|
||||
struct inet_request_sock *ireq = inet_rsk(req);
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
struct tcphdr *th;
|
||||
struct sk_buff *skb;
|
||||
const struct tcp_sock *tp = tcp_sk(sk);
|
||||
struct tcp_md5sig_key *md5 = NULL;
|
||||
struct tcp_out_options opts;
|
||||
struct sk_buff *skb;
|
||||
int tcp_header_size;
|
||||
struct tcphdr *th;
|
||||
u16 user_mss;
|
||||
int mss;
|
||||
|
||||
skb = sock_wmalloc(sk, MAX_TCP_HEADER, 1, GFP_ATOMIC);
|
||||
/* sk is a const pointer, because we want to express multiple cpus
|
||||
* might call us concurrently.
|
||||
* sock_wmalloc() will change sk->sk_wmem_alloc in an atomic way.
|
||||
*/
|
||||
skb = sock_wmalloc((struct sock *)sk, MAX_TCP_HEADER, 1, GFP_ATOMIC);
|
||||
if (unlikely(!skb)) {
|
||||
dst_release(dst);
|
||||
return NULL;
|
||||
@ -2968,8 +2973,9 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
|
||||
skb_dst_set(skb, dst);
|
||||
|
||||
mss = dst_metric_advmss(dst);
|
||||
if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss)
|
||||
mss = tp->rx_opt.user_mss;
|
||||
user_mss = READ_ONCE(tp->rx_opt.user_mss);
|
||||
if (user_mss && user_mss < mss)
|
||||
mss = user_mss;
|
||||
|
||||
memset(&opts, 0, sizeof(opts));
|
||||
#ifdef CONFIG_SYN_COOKIES
|
||||
@ -3009,7 +3015,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
|
||||
|
||||
/* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */
|
||||
th->window = htons(min(req->rcv_wnd, 65535U));
|
||||
tcp_options_write((__be32 *)(th + 1), tp, &opts);
|
||||
tcp_options_write((__be32 *)(th + 1), NULL, &opts);
|
||||
th->doff = (tcp_header_size >> 2);
|
||||
TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_OUTSEGS);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user