diff options
-rw-r--r-- | include/net/sctp/command.h | 3 | ||||
-rw-r--r-- | include/net/sctp/structs.h | 1 | ||||
-rw-r--r-- | net/sctp/chunk.c | 13 | ||||
-rw-r--r-- | net/sctp/sm_sideeffect.c | 29 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 4 | ||||
-rw-r--r-- | net/sctp/socket.c | 26 |
6 files changed, 61 insertions, 15 deletions
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h index 3b966802e05d..8be5135ff7aa 100644 --- a/include/net/sctp/command.h +++ b/include/net/sctp/command.h | |||
@@ -106,6 +106,7 @@ typedef enum { | |||
106 | SCTP_CMD_ASSOC_SHKEY, /* generate the association shared keys */ | 106 | SCTP_CMD_ASSOC_SHKEY, /* generate the association shared keys */ |
107 | SCTP_CMD_T1_RETRAN, /* Mark for retransmission after T1 timeout */ | 107 | SCTP_CMD_T1_RETRAN, /* Mark for retransmission after T1 timeout */ |
108 | SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */ | 108 | SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */ |
109 | SCTP_CMD_SEND_MSG, /* Send the whole use message */ | ||
109 | SCTP_CMD_LAST | 110 | SCTP_CMD_LAST |
110 | } sctp_verb_t; | 111 | } sctp_verb_t; |
111 | 112 | ||
@@ -139,6 +140,7 @@ typedef union { | |||
139 | struct sctp_ulpevent *ulpevent; | 140 | struct sctp_ulpevent *ulpevent; |
140 | struct sctp_packet *packet; | 141 | struct sctp_packet *packet; |
141 | sctp_sackhdr_t *sackh; | 142 | sctp_sackhdr_t *sackh; |
143 | struct sctp_datamsg *msg; | ||
142 | } sctp_arg_t; | 144 | } sctp_arg_t; |
143 | 145 | ||
144 | /* We are simulating ML type constructors here. | 146 | /* We are simulating ML type constructors here. |
@@ -188,6 +190,7 @@ SCTP_ARG_CONSTRUCTOR(PEER_INIT, sctp_init_chunk_t *, init) | |||
188 | SCTP_ARG_CONSTRUCTOR(ULPEVENT, struct sctp_ulpevent *, ulpevent) | 190 | SCTP_ARG_CONSTRUCTOR(ULPEVENT, struct sctp_ulpevent *, ulpevent) |
189 | SCTP_ARG_CONSTRUCTOR(PACKET, struct sctp_packet *, packet) | 191 | SCTP_ARG_CONSTRUCTOR(PACKET, struct sctp_packet *, packet) |
190 | SCTP_ARG_CONSTRUCTOR(SACKH, sctp_sackhdr_t *, sackh) | 192 | SCTP_ARG_CONSTRUCTOR(SACKH, sctp_sackhdr_t *, sackh) |
193 | SCTP_ARG_CONSTRUCTOR(DATAMSG, struct sctp_datamsg *, msg) | ||
191 | 194 | ||
192 | typedef struct { | 195 | typedef struct { |
193 | sctp_arg_t obj; | 196 | sctp_arg_t obj; |
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index edfcacf3250e..97024faaa08f 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -643,6 +643,7 @@ struct sctp_datamsg { | |||
643 | struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *, | 643 | struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *, |
644 | struct sctp_sndrcvinfo *, | 644 | struct sctp_sndrcvinfo *, |
645 | struct msghdr *, int len); | 645 | struct msghdr *, int len); |
646 | void sctp_datamsg_free(struct sctp_datamsg *); | ||
646 | void sctp_datamsg_put(struct sctp_datamsg *); | 647 | void sctp_datamsg_put(struct sctp_datamsg *); |
647 | void sctp_chunk_fail(struct sctp_chunk *, int error); | 648 | void sctp_chunk_fail(struct sctp_chunk *, int error); |
648 | int sctp_chunk_abandoned(struct sctp_chunk *); | 649 | int sctp_chunk_abandoned(struct sctp_chunk *); |
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c index 7acaf15679b6..645577ddc33e 100644 --- a/net/sctp/chunk.c +++ b/net/sctp/chunk.c | |||
@@ -73,6 +73,19 @@ SCTP_STATIC struct sctp_datamsg *sctp_datamsg_new(gfp_t gfp) | |||
73 | return msg; | 73 | return msg; |
74 | } | 74 | } |
75 | 75 | ||
76 | void sctp_datamsg_free(struct sctp_datamsg *msg) | ||
77 | { | ||
78 | struct sctp_chunk *chunk; | ||
79 | |||
80 | /* This doesn't have to be a _safe vairant because | ||
81 | * sctp_chunk_free() only drops the refs. | ||
82 | */ | ||
83 | list_for_each_entry(chunk, &msg->chunks, frag_list) | ||
84 | sctp_chunk_free(chunk); | ||
85 | |||
86 | sctp_datamsg_put(msg); | ||
87 | } | ||
88 | |||
76 | /* Final destructruction of datamsg memory. */ | 89 | /* Final destructruction of datamsg memory. */ |
77 | static void sctp_datamsg_destroy(struct sctp_datamsg *msg) | 90 | static void sctp_datamsg_destroy(struct sctp_datamsg *msg) |
78 | { | 91 | { |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 86426aac1600..238adf7978e9 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -931,6 +931,27 @@ static void sctp_cmd_t1_timer_update(struct sctp_association *asoc, | |||
931 | 931 | ||
932 | } | 932 | } |
933 | 933 | ||
934 | /* Send the whole message, chunk by chunk, to the outqueue. | ||
935 | * This way the whole message is queued up and bundling if | ||
936 | * encouraged for small fragments. | ||
937 | */ | ||
938 | static int sctp_cmd_send_msg(struct sctp_association *asoc, | ||
939 | struct sctp_datamsg *msg) | ||
940 | { | ||
941 | struct sctp_chunk *chunk; | ||
942 | int error = 0; | ||
943 | |||
944 | list_for_each_entry(chunk, &msg->chunks, frag_list) { | ||
945 | error = sctp_outq_tail(&asoc->outqueue, chunk); | ||
946 | if (error) | ||
947 | break; | ||
948 | } | ||
949 | |||
950 | return error; | ||
951 | } | ||
952 | |||
953 | |||
954 | |||
934 | /* These three macros allow us to pull the debugging code out of the | 955 | /* These three macros allow us to pull the debugging code out of the |
935 | * main flow of sctp_do_sm() to keep attention focused on the real | 956 | * main flow of sctp_do_sm() to keep attention focused on the real |
936 | * functionality there. | 957 | * functionality there. |
@@ -1575,7 +1596,13 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1575 | case SCTP_CMD_UPDATE_INITTAG: | 1596 | case SCTP_CMD_UPDATE_INITTAG: |
1576 | asoc->peer.i.init_tag = cmd->obj.u32; | 1597 | asoc->peer.i.init_tag = cmd->obj.u32; |
1577 | break; | 1598 | break; |
1578 | 1599 | case SCTP_CMD_SEND_MSG: | |
1600 | if (!asoc->outqueue.cork) { | ||
1601 | sctp_outq_cork(&asoc->outqueue); | ||
1602 | local_cork = 1; | ||
1603 | } | ||
1604 | error = sctp_cmd_send_msg(asoc, cmd->obj.msg); | ||
1605 | break; | ||
1579 | default: | 1606 | default: |
1580 | printk(KERN_WARNING "Impossible command: %u, %p\n", | 1607 | printk(KERN_WARNING "Impossible command: %u, %p\n", |
1581 | cmd->verb, cmd->obj.ptr); | 1608 | cmd->verb, cmd->obj.ptr); |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 50225dd2e6dc..910926906a3a 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -4555,9 +4555,9 @@ sctp_disposition_t sctp_sf_do_prm_send(const struct sctp_endpoint *ep, | |||
4555 | void *arg, | 4555 | void *arg, |
4556 | sctp_cmd_seq_t *commands) | 4556 | sctp_cmd_seq_t *commands) |
4557 | { | 4557 | { |
4558 | struct sctp_chunk *chunk = arg; | 4558 | struct sctp_datamsg *msg = arg; |
4559 | 4559 | ||
4560 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(chunk)); | 4560 | sctp_add_cmd_sf(commands, SCTP_CMD_SEND_MSG, SCTP_DATAMSG(msg)); |
4561 | return SCTP_DISPOSITION_CONSUME; | 4561 | return SCTP_DISPOSITION_CONSUME; |
4562 | } | 4562 | } |
4563 | 4563 | ||
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index a7e544e3f28a..95a5623d79a0 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -1814,20 +1814,22 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1814 | sctp_set_owner_w(chunk); | 1814 | sctp_set_owner_w(chunk); |
1815 | 1815 | ||
1816 | chunk->transport = chunk_tp; | 1816 | chunk->transport = chunk_tp; |
1817 | |||
1818 | /* Send it to the lower layers. Note: all chunks | ||
1819 | * must either fail or succeed. The lower layer | ||
1820 | * works that way today. Keep it that way or this | ||
1821 | * breaks. | ||
1822 | */ | ||
1823 | err = sctp_primitive_SEND(asoc, chunk); | ||
1824 | /* Did the lower layer accept the chunk? */ | ||
1825 | if (err) | ||
1826 | sctp_chunk_free(chunk); | ||
1827 | SCTP_DEBUG_PRINTK("We sent primitively.\n"); | ||
1828 | } | 1817 | } |
1829 | 1818 | ||
1830 | sctp_datamsg_put(datamsg); | 1819 | /* Send it to the lower layers. Note: all chunks |
1820 | * must either fail or succeed. The lower layer | ||
1821 | * works that way today. Keep it that way or this | ||
1822 | * breaks. | ||
1823 | */ | ||
1824 | err = sctp_primitive_SEND(asoc, datamsg); | ||
1825 | /* Did the lower layer accept the chunk? */ | ||
1826 | if (err) | ||
1827 | sctp_datamsg_free(datamsg); | ||
1828 | else | ||
1829 | sctp_datamsg_put(datamsg); | ||
1830 | |||
1831 | SCTP_DEBUG_PRINTK("We sent primitively.\n"); | ||
1832 | |||
1831 | if (err) | 1833 | if (err) |
1832 | goto out_free; | 1834 | goto out_free; |
1833 | else | 1835 | else |