diff mbox series

[net-next] net: mptcp: don't hang before sending 'MP capable with data'

Message ID da448d7e0a2459519394ab0c398875061f2bf1d0.1583952277.git.dcaratti@redhat.com
State Deferred, archived
Delegated to: Davide Caratti
Headers show
Series [net-next] net: mptcp: don't hang before sending 'MP capable with data' | expand

Commit Message

Davide Caratti March 11, 2020, 6:50 p.m. UTC
the following packetdrill script

  socket(..., SOCK_STREAM, IPPROTO_MPTCP) = 3
  fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
  fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
  connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress)
  > S 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8,mpcapable v1 flags[flag_h] nokey>
  < S. 0:0(0) ack 1 win 65535 <mss 1460,sackOK,TS val 700 ecr 100,nop,wscale 8,mpcapable v1 flags[flag_h] key[skey=2]>
  > . 1:1(0) ack 1 win 256 <nop, nop, TS val 100 ecr 700,mpcapable v1 flags[flag_h] key[ckey,skey]>
  getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
  fcntl(3, F_SETFL, O_RDWR) = 0
  write(3, ..., 1000) = 1000

doesn't transmit 1KB data packet after a successful three-way-handshake,
using mp_capable with data as required by protocol v1, and write() hangs
forever:

 PID: 973    TASK: ffff97dd399cae80  CPU: 1   COMMAND: "packetdrill"
  #0 [ffffa9b94062fb78] __schedule at ffffffff9c90a000
  #1 [ffffa9b94062fc08] schedule at ffffffff9c90a4a0
  #2 [ffffa9b94062fc18] schedule_timeout at ffffffff9c90e00d
  #3 [ffffa9b94062fc90] wait_woken at ffffffff9c120184
  #4 [ffffa9b94062fcb0] sk_stream_wait_connect at ffffffff9c75b064
  #5 [ffffa9b94062fd20] mptcp_sendmsg at ffffffff9c8e801c
  #6 [ffffa9b94062fdc0] sock_sendmsg at ffffffff9c747324
  #7 [ffffa9b94062fdd8] sock_write_iter at ffffffff9c7473c7
  #8 [ffffa9b94062fe48] new_sync_write at ffffffff9c302976
  #9 [ffffa9b94062fed0] vfs_write at ffffffff9c305685
 #10 [ffffa9b94062ff00] ksys_write at ffffffff9c305985
 #11 [ffffa9b94062ff38] do_syscall_64 at ffffffff9c004475
 #12 [ffffa9b94062ff50] entry_SYSCALL_64_after_hwframe at ffffffff9ca0008c
     RIP: 00007f959407eaf7  RSP: 00007ffe9e95a910  RFLAGS: 00000293
     RAX: ffffffffffffffda  RBX: 0000000000000008  RCX: 00007f959407eaf7
     RDX: 00000000000003e8  RSI: 0000000001785fe0  RDI: 0000000000000008
     RBP: 0000000001785fe0   R8: 0000000000000000   R9: 0000000000000003
     R10: 0000000000000007  R11: 0000000000000293  R12: 00000000000003e8
     R13: 00007ffe9e95ae30  R14: 0000000000000000  R15: 0000000000000000
     ORIG_RAX: 0000000000000001  CS: 0033  SS: 002b

Fix it ensuring that socket state is TCP_ESTABLISHED on reception of the
third ack.

Fixes: 1954b86016cf ("mptcp: Check connection state before attempting send")
Suggested-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Davide Caratti <dcaratti@redhat.com>
---
 net/mptcp/protocol.c | 4 ++++
 1 file changed, 4 insertions(+)

Comments

David Miller March 12, 2020, 7 a.m. UTC | #1
From: Davide Caratti <dcaratti@redhat.com>
Date: Wed, 11 Mar 2020 19:50:53 +0100

> the following packetdrill script
> 
>   socket(..., SOCK_STREAM, IPPROTO_MPTCP) = 3
>   fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
>   fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
>   connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress)
>   > S 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8,mpcapable v1 flags[flag_h] nokey>
>   < S. 0:0(0) ack 1 win 65535 <mss 1460,sackOK,TS val 700 ecr 100,nop,wscale 8,mpcapable v1 flags[flag_h] key[skey=2]>
>   > . 1:1(0) ack 1 win 256 <nop, nop, TS val 100 ecr 700,mpcapable v1 flags[flag_h] key[ckey,skey]>
>   getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
>   fcntl(3, F_SETFL, O_RDWR) = 0
>   write(3, ..., 1000) = 1000
> 
> doesn't transmit 1KB data packet after a successful three-way-handshake,
> using mp_capable with data as required by protocol v1, and write() hangs
> forever:
> 
>  PID: 973    TASK: ffff97dd399cae80  CPU: 1   COMMAND: "packetdrill"
>   #0 [ffffa9b94062fb78] __schedule at ffffffff9c90a000
>   #1 [ffffa9b94062fc08] schedule at ffffffff9c90a4a0
>   #2 [ffffa9b94062fc18] schedule_timeout at ffffffff9c90e00d
>   #3 [ffffa9b94062fc90] wait_woken at ffffffff9c120184
>   #4 [ffffa9b94062fcb0] sk_stream_wait_connect at ffffffff9c75b064
>   #5 [ffffa9b94062fd20] mptcp_sendmsg at ffffffff9c8e801c
>   #6 [ffffa9b94062fdc0] sock_sendmsg at ffffffff9c747324
>   #7 [ffffa9b94062fdd8] sock_write_iter at ffffffff9c7473c7
>   #8 [ffffa9b94062fe48] new_sync_write at ffffffff9c302976
>   #9 [ffffa9b94062fed0] vfs_write at ffffffff9c305685
>  #10 [ffffa9b94062ff00] ksys_write at ffffffff9c305985
>  #11 [ffffa9b94062ff38] do_syscall_64 at ffffffff9c004475
>  #12 [ffffa9b94062ff50] entry_SYSCALL_64_after_hwframe at ffffffff9ca0008c
>      RIP: 00007f959407eaf7  RSP: 00007ffe9e95a910  RFLAGS: 00000293
>      RAX: ffffffffffffffda  RBX: 0000000000000008  RCX: 00007f959407eaf7
>      RDX: 00000000000003e8  RSI: 0000000001785fe0  RDI: 0000000000000008
>      RBP: 0000000001785fe0   R8: 0000000000000000   R9: 0000000000000003
>      R10: 0000000000000007  R11: 0000000000000293  R12: 00000000000003e8
>      R13: 00007ffe9e95ae30  R14: 0000000000000000  R15: 0000000000000000
>      ORIG_RAX: 0000000000000001  CS: 0033  SS: 002b
> 
> Fix it ensuring that socket state is TCP_ESTABLISHED on reception of the
> third ack.
> 
> Fixes: 1954b86016cf ("mptcp: Check connection state before attempting send")
> Suggested-by: Paolo Abeni <pabeni@redhat.com>
> Signed-off-by: Davide Caratti <dcaratti@redhat.com>

Applied, thanks.
diff mbox series

Patch

diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 95007e433109..c0cef07f4382 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1049,6 +1049,10 @@  void mptcp_finish_connect(struct sock *ssk)
 	WRITE_ONCE(msk->write_seq, subflow->idsn + 1);
 	WRITE_ONCE(msk->ack_seq, ack_seq);
 	WRITE_ONCE(msk->can_ack, 1);
+	if (inet_sk_state_load(sk) != TCP_ESTABLISHED) {
+		inet_sk_state_store(sk, TCP_ESTABLISHED);
+		sk->sk_state_change(sk);
+	}
 }
 
 static void mptcp_sock_graft(struct sock *sk, struct socket *parent)