mptcp: Correctly check for the state in mptcp_sk_can_recv

As we compare it with the flags, we have to use TCPF_*.
Otherwise, the check is just simply wrong... Surprising how long this
bug has been in there.

Fixes: 316f688300c09 (Fix: Don't account non-established subflows in send/rcv-buffer)
Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
mptcp: Do not continue processing when meta has been closed

The reception of the data-fin changes the state of the meta-socket.
After this reception, we should stop processing data.

After mptcp_queue_skb and the reception of a data-fin, it will return
-1. Then, in mptcp_data_ready, we goto restart. So, just move restart a
bit higher and fix the check.

The problem is still present, if the meta has gone into time-wait.
Fixing this is much more complex. Handling the meta correctly in
time-wait cannot be done with mptcp_data_ready. We probably should
create a real time-wait socket for the meta and do the processing in
tcp_tw_state_process. But that's far from a trivial fix...

Issue #39: https://github.com/multipath-tcp/mptcp/issues/39

Fixes: Zero-day bug
Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
mptcp: Always send the third ack of the 3-way handshake

There is no space to combine an MP_CAPABLE (or MP_JOIN) with data, as
there is not enough option space.

So, we send it out directly.

Fixes: Zero-day bug
Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
mptcp: fullmesh: Always announce all addresses

If a connection is unidirectionally sending its data and there is no
space in the third ack (or the data segments) to add the ADD_ADDR, this
ADD_ADDR will never be sent. The problem is that we call full-mesh but
do not trigger the sending of a third ack.

We could simply call tcp_send_ack inside fullmesh_new_session, which
would work on the server-side, but on the client-side we would then send
this ADD_ADDR before the third ack + MP_CAPABLE. Then, we break hosts
who support syn-cookies on the server side.

So, the fix is to move the call to mptcp_update_metasocket (who calls
new_session) a bit later on the client-side. Additionally, we provide to
new_session the master-socket, as this is at this point the only one who
can send something.
On the server-side everything is fine, because at the point when we
receive the third ack we are ok to send an ADD_ADDR.

Issue #48: https://github.com/multipath-tcp/mptcp/issues/48

Reported-by: Simone Ferlin-Oliveira <ferlin@simula.no>
Fixes: c31d21d039d80 (Modularize the path-manager)
Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
mptcp: Correctly handle keepalive on active opener

f40efe40d0 (mptcp: Correct support of TCP-keepalive cont'd) enabled
correct handling of keepalive on the passive opener, by changing the
condition in tcp_create_openreq_child to prevent resetting the keepalive
timer on new subflows. However, this only fixed it on the server-side.

This patch fixes the behavior now also for the active opener.
Keepalive setting/deleting of the timer is now entirely handled in
MPTCP-functions. First, when allocating the mpcb, we set the keepalive
timer in mptcp_mpcb_inherit_sockopts. This, because on the client-side,
the keepalive timer is started in tcp_finish_connect - a function never
called on the meta-socket. At the same time, we cancel eventual started
timers on the master sk.

Further, for new subflows, we kill their keepalive-timer inside
mptcp_sub_inherit_sockopts, which is called from mptcp_add_sock. There
are two cases here:

* active opener: Actually nothing special to be done here. The
  keepalive-flag is not inherited from the meta-socket.
* passive opener: The keepalive-flag has been inherited from the
  meta-socket through mptcp_inherit_sk. And the timer has been started
  in tcp_create_openreq_child. So, we unset the flag and delete the timer.

Fixes: f40efe40d0 (mptcp: Correct support of TCP-keepalive cont'd)
Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
mptcp: Always set the PSH-flag when probing for the window

tcp_write_wakeup always sets the PSH-flag. We have to do the same.

Fixes: a23c25090d7f9 (Handle probe-timer at the meta-level)
Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
mptcp: Some small fixes to the fallback

This patch contains several small fixes to fallback:

1. When a subflow enters time-wait, we create the mptcp_tw-struct that
   enables the subsocket to send data-acks and act upon mp-fastclose,... If
   we are in receiving-infinite-mapping mode, we should never add
   data-acks. So, we prevent this by simply not creating the
   mptcp_tw-struct.

2. In mptcp_prevalidate_skb, when doing a seamless fallback, we should
   force send_infinite_mapping to 0. Because, it *might* have been set to
   1, if a data-segment without DSS-option contains an MP_FAIL (I know,
   such combination does not make sense, but a "malicious" host might do
   it - see
   https://github.com/cpaasch/packetdrill_mptcp/blob/more_tests/gtests/net/packetdrill/examples/mptcp/mp_fail/mp_fail_specified_client.pkt)

3. In mptcp_skb_entail, we have to call mptcp_combine_dfin after the
   'if' about send_infinite_mapping. Because, otherwise if we receive an
   MP_FAIL (so we should fallback to infinite) and the next segment is a
   DATA_FIN, we will not combine it with a subflow-fin and thus the
   connection cannot be closed anymmore (because in infinite mode, we have
   to set the subflow-fin to signal a data-fin)

4. In mptcp_established_options, first we should be able to fallback
   even if we are not yet fully established. Second, we should check for
   MPTCPHDR_INF only on segments with actual data (mptcp_is_data_seq).

Fixes: Zero-day bug
Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
mptcp: Fix TCP_DEFER_ACCEPT

The socket-option DEFER_ACCEPT allows to defer the accept of a new
connection until data has been received (or a timer expired).

For MPTCP the story is twofold:

1. On the initial subflow we still want to support defer-accept.
2. On subsequent subflows we do not want to support it, because we have
   to reply with the third ack with a fourth ack (after verifying the
   hmac)

First, to allow defer-accept on the initial subflow, we remove the
additional check in tcp_check_req. The comment there says that we do not
support defer-accept because we want to support receiving options in the
third ack. But, this behavior is already broken, as one can see that
'mopt' is not used at all in mptcp_check_req_master. If we want to
support receiving options in the third ack, we should do as the comment
suggests - storing them in the requests socket.

Second, to prevent defer-accept on additional subflows, we simply clear
the flag in the meta-sk. We also must prevent setting defer-accept on an
established meta-sk. This, by adding a check in do_tcp_setsockopt.

Fixes: Zero-day bug
Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
mptcp: Fix IP_RECVERR

The socket-option IP_RECVERR forces sockets to report soft errors to the
application. With MPTCP, this reporting ends up in
mptcp_sock_def_error_report, closing the socket. That's not really what
we want. soft-errors are not really a concern for the subflows. We can
simply continue.

So, we should unset IP_RECVERR on subflows, so that they do not report
the error.

Longterm, we should probably define when soft errors need to be reported
back to the application in case MPTCP is being used.

Issue #46: https://github.com/multipath-tcp/mptcp/issues/46

Fixes: Zero-day bug
Reported-by: Laurent Deru <laurent.deru@cetic.be>
Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
mptcp: Explicitly set reserved-fields of MP_JOIN to 0

In the third ack of the MP_JOIN, the address-id is actually a reserved
field (cfr. RFC 6824, p. 21). So, we should set the reserved field
explicitly to 0 as requested by the RFC.

Actually, prior (by chance) this was still correct, because opts is
memset'ed to 0 and addr_id is not changed for the third ack in
mptcp_established_options.

Fixes: Zero-day bug
Reported-by: Fabien Duchene <fabien.duchene@uclouvain.be>
Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>