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

Commit 4ea0c32f authored by Xin Long's avatar Xin Long Committed by David S. Miller
Browse files

sctp: add support for MSG_MORE

This patch is to add support for MSG_MORE on sctp.

It adds force_delay in sctp_datamsg to save MSG_MORE, and sets it after
creating datamsg according to the send flag. sctp_packet_can_append_data
then uses it to decide if the chunks of this msg will be sent at once or
delay it.

Note that unlike [1], this patch saves MSG_MORE in datamsg, instead of
in assoc. As sctp enqueues the chunks first, then dequeue them one by
one. If it's saved in assoc,the current msg's send flag (MSG_MORE) may
affect other chunks' bundling.

Since last patch, sctp flush out queue once assoc state falls into
SHUTDOWN_PENDING, the close block problem mentioned in [1] has been
solved as well.

[1] https://patchwork.ozlabs.org/patch/372404/



Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b7018d0b
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -497,6 +497,7 @@ struct sctp_datamsg {
	/* Did the messenge fail to send? */
	/* Did the messenge fail to send? */
	int send_error;
	int send_error;
	u8 send_failed:1,
	u8 send_failed:1,
	   force_delay:1,
	   can_delay;	    /* should this message be Nagle delayed */
	   can_delay;	    /* should this message be Nagle delayed */
};
};


+3 −6
Original line number Original line Diff line number Diff line
@@ -704,18 +704,15 @@ static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
	 * unacknowledged.
	 * unacknowledged.
	 */
	 */


	if (sctp_sk(asoc->base.sk)->nodelay)
	if ((sctp_sk(asoc->base.sk)->nodelay || inflight == 0) &&
		/* Nagle disabled */
	    !chunk->msg->force_delay)
		/* Nothing unacked */
		return SCTP_XMIT_OK;
		return SCTP_XMIT_OK;


	if (!sctp_packet_empty(packet))
	if (!sctp_packet_empty(packet))
		/* Append to packet */
		/* Append to packet */
		return SCTP_XMIT_OK;
		return SCTP_XMIT_OK;


	if (inflight == 0)
		/* Nothing unacked */
		return SCTP_XMIT_OK;

	if (!sctp_state(asoc, ESTABLISHED))
	if (!sctp_state(asoc, ESTABLISHED))
		return SCTP_XMIT_OK;
		return SCTP_XMIT_OK;


+1 −0
Original line number Original line Diff line number Diff line
@@ -1964,6 +1964,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
		err = PTR_ERR(datamsg);
		err = PTR_ERR(datamsg);
		goto out_free;
		goto out_free;
	}
	}
	datamsg->force_delay = !!(msg->msg_flags & MSG_MORE);


	/* Now send the (possibly) fragmented message. */
	/* Now send the (possibly) fragmented message. */
	list_for_each_entry(chunk, &datamsg->chunks, frag_list) {
	list_for_each_entry(chunk, &datamsg->chunks, frag_list) {