aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/outqueue.c
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2008-06-19 19:08:18 -0400
committerDavid S. Miller <davem@davemloft.net>2008-06-19 19:08:18 -0400
commit2e3216cd54b142ba605e87522e15f42e0c4e3996 (patch)
treeda4d7a6ff4811d9f38b81c70f08b221b575e1254 /net/sctp/outqueue.c
parent7115e632f90952454ab6426e0d2151327162a30f (diff)
sctp: Follow security requirement of responding with 1 packet
RFC 4960, Section 11.4. Protection of Non-SCTP-Capable Hosts When an SCTP stack receives a packet containing multiple control or DATA chunks and the processing of the packet requires the sending of multiple chunks in response, the sender of the response chunk(s) MUST NOT send more than one packet. If bundling is supported, multiple response chunks that fit into a single packet MAY be bundled together into one single response packet. If bundling is not supported, then the sender MUST NOT send more than one response chunk and MUST discard all other responses. Note that this rule does NOT apply to a SACK chunk, since a SACK chunk is, in itself, a response to DATA and a SACK does not require a response of more DATA. We implement this by not servicing our outqueue until we reach the end of the packet. This enables maximum bundling. We also identify 'response' chunks and make sure that we only send 1 packet when sending such chunks. Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/outqueue.c')
-rw-r--r--net/sctp/outqueue.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index ace6770e9048..70ead8dc3485 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -702,6 +702,7 @@ int sctp_outq_uncork(struct sctp_outq *q)
702 return error; 702 return error;
703} 703}
704 704
705
705/* 706/*
706 * Try to flush an outqueue. 707 * Try to flush an outqueue.
707 * 708 *
@@ -725,6 +726,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
725 sctp_xmit_t status; 726 sctp_xmit_t status;
726 int error = 0; 727 int error = 0;
727 int start_timer = 0; 728 int start_timer = 0;
729 int one_packet = 0;
728 730
729 /* These transports have chunks to send. */ 731 /* These transports have chunks to send. */
730 struct list_head transport_list; 732 struct list_head transport_list;
@@ -830,20 +832,33 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
830 if (sctp_test_T_bit(chunk)) { 832 if (sctp_test_T_bit(chunk)) {
831 packet->vtag = asoc->c.my_vtag; 833 packet->vtag = asoc->c.my_vtag;
832 } 834 }
833 case SCTP_CID_SACK: 835 /* The following chunks are "response" chunks, i.e.
834 case SCTP_CID_HEARTBEAT: 836 * they are generated in response to something we
837 * received. If we are sending these, then we can
838 * send only 1 packet containing these chunks.
839 */
835 case SCTP_CID_HEARTBEAT_ACK: 840 case SCTP_CID_HEARTBEAT_ACK:
836 case SCTP_CID_SHUTDOWN:
837 case SCTP_CID_SHUTDOWN_ACK: 841 case SCTP_CID_SHUTDOWN_ACK:
838 case SCTP_CID_ERROR:
839 case SCTP_CID_COOKIE_ECHO:
840 case SCTP_CID_COOKIE_ACK: 842 case SCTP_CID_COOKIE_ACK:
841 case SCTP_CID_ECN_ECNE: 843 case SCTP_CID_COOKIE_ECHO:
844 case SCTP_CID_ERROR:
842 case SCTP_CID_ECN_CWR: 845 case SCTP_CID_ECN_CWR:
843 case SCTP_CID_ASCONF:
844 case SCTP_CID_ASCONF_ACK: 846 case SCTP_CID_ASCONF_ACK:
847 one_packet = 1;
848 /* Fall throught */
849
850 case SCTP_CID_SACK:
851 case SCTP_CID_HEARTBEAT:
852 case SCTP_CID_SHUTDOWN:
853 case SCTP_CID_ECN_ECNE:
854 case SCTP_CID_ASCONF:
845 case SCTP_CID_FWD_TSN: 855 case SCTP_CID_FWD_TSN:
846 sctp_packet_transmit_chunk(packet, chunk); 856 status = sctp_packet_transmit_chunk(packet, chunk,
857 one_packet);
858 if (status != SCTP_XMIT_OK) {
859 /* put the chunk back */
860 list_add(&chunk->list, &q->control_chunk_list);
861 }
847 break; 862 break;
848 863
849 default: 864 default:
@@ -974,7 +989,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
974 atomic_read(&chunk->skb->users) : -1); 989 atomic_read(&chunk->skb->users) : -1);
975 990
976 /* Add the chunk to the packet. */ 991 /* Add the chunk to the packet. */
977 status = sctp_packet_transmit_chunk(packet, chunk); 992 status = sctp_packet_transmit_chunk(packet, chunk, 0);
978 993
979 switch (status) { 994 switch (status) {
980 case SCTP_XMIT_PMTU_FULL: 995 case SCTP_XMIT_PMTU_FULL:
@@ -1239,7 +1254,6 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
1239 * Make sure the empty queue handler will get run later. 1254 * Make sure the empty queue handler will get run later.
1240 */ 1255 */
1241 q->empty = (list_empty(&q->out_chunk_list) && 1256 q->empty = (list_empty(&q->out_chunk_list) &&
1242 list_empty(&q->control_chunk_list) &&
1243 list_empty(&q->retransmit)); 1257 list_empty(&q->retransmit));
1244 if (!q->empty) 1258 if (!q->empty)
1245 goto finish; 1259 goto finish;