diff options
Diffstat (limited to 'net')
-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 |
4 files changed, 57 insertions, 15 deletions
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 |