diff options
author | Ivan Skytte Jorgensen <isj-sctp@i1.dk> | 2006-12-13 19:34:22 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-13 19:48:29 -0500 |
commit | 6ab792f577012312a760a3a1e679ae8fae012442 (patch) | |
tree | 7d60307266f3d81afdf06ec14e646d2f7a1b4ef7 /net | |
parent | 882a382c3e0b432fa91672e1c2754cac3f5a6b4f (diff) |
[SCTP]: Add support for SCTP_CONTEXT socket option.
Signed-off-by: Ivan Skytte Jorgensen <isj-sctp@i1.dk>
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/sctp/associola.c | 1 | ||||
-rw-r--r-- | net/sctp/socket.c | 84 | ||||
-rw-r--r-- | net/sctp/ulpevent.c | 4 |
3 files changed, 88 insertions, 1 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index ad0057db0f91..5db95caed0a3 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -298,6 +298,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
298 | asoc->default_flags = sp->default_flags; | 298 | asoc->default_flags = sp->default_flags; |
299 | asoc->default_context = sp->default_context; | 299 | asoc->default_context = sp->default_context; |
300 | asoc->default_timetolive = sp->default_timetolive; | 300 | asoc->default_timetolive = sp->default_timetolive; |
301 | asoc->default_rcv_context = sp->default_rcv_context; | ||
301 | 302 | ||
302 | return asoc; | 303 | return asoc; |
303 | 304 | ||
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index fa29eae83e91..bdd8bd428b64 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -2746,6 +2746,46 @@ static int sctp_setsockopt_adaption_layer(struct sock *sk, char __user *optval, | |||
2746 | return 0; | 2746 | return 0; |
2747 | } | 2747 | } |
2748 | 2748 | ||
2749 | /* | ||
2750 | * 7.1.29. Set or Get the default context (SCTP_CONTEXT) | ||
2751 | * | ||
2752 | * The context field in the sctp_sndrcvinfo structure is normally only | ||
2753 | * used when a failed message is retrieved holding the value that was | ||
2754 | * sent down on the actual send call. This option allows the setting of | ||
2755 | * a default context on an association basis that will be received on | ||
2756 | * reading messages from the peer. This is especially helpful in the | ||
2757 | * one-2-many model for an application to keep some reference to an | ||
2758 | * internal state machine that is processing messages on the | ||
2759 | * association. Note that the setting of this value only effects | ||
2760 | * received messages from the peer and does not effect the value that is | ||
2761 | * saved with outbound messages. | ||
2762 | */ | ||
2763 | static int sctp_setsockopt_context(struct sock *sk, char __user *optval, | ||
2764 | int optlen) | ||
2765 | { | ||
2766 | struct sctp_assoc_value params; | ||
2767 | struct sctp_sock *sp; | ||
2768 | struct sctp_association *asoc; | ||
2769 | |||
2770 | if (optlen != sizeof(struct sctp_assoc_value)) | ||
2771 | return -EINVAL; | ||
2772 | if (copy_from_user(¶ms, optval, optlen)) | ||
2773 | return -EFAULT; | ||
2774 | |||
2775 | sp = sctp_sk(sk); | ||
2776 | |||
2777 | if (params.assoc_id != 0) { | ||
2778 | asoc = sctp_id2assoc(sk, params.assoc_id); | ||
2779 | if (!asoc) | ||
2780 | return -EINVAL; | ||
2781 | asoc->default_rcv_context = params.assoc_value; | ||
2782 | } else { | ||
2783 | sp->default_rcv_context = params.assoc_value; | ||
2784 | } | ||
2785 | |||
2786 | return 0; | ||
2787 | } | ||
2788 | |||
2749 | /* API 6.2 setsockopt(), getsockopt() | 2789 | /* API 6.2 setsockopt(), getsockopt() |
2750 | * | 2790 | * |
2751 | * Applications use setsockopt() and getsockopt() to set or retrieve | 2791 | * Applications use setsockopt() and getsockopt() to set or retrieve |
@@ -2857,6 +2897,9 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname, | |||
2857 | case SCTP_ADAPTION_LAYER: | 2897 | case SCTP_ADAPTION_LAYER: |
2858 | retval = sctp_setsockopt_adaption_layer(sk, optval, optlen); | 2898 | retval = sctp_setsockopt_adaption_layer(sk, optval, optlen); |
2859 | break; | 2899 | break; |
2900 | case SCTP_CONTEXT: | ||
2901 | retval = sctp_setsockopt_context(sk, optval, optlen); | ||
2902 | break; | ||
2860 | 2903 | ||
2861 | default: | 2904 | default: |
2862 | retval = -ENOPROTOOPT; | 2905 | retval = -ENOPROTOOPT; |
@@ -3016,6 +3059,8 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
3016 | sp->default_context = 0; | 3059 | sp->default_context = 0; |
3017 | sp->default_timetolive = 0; | 3060 | sp->default_timetolive = 0; |
3018 | 3061 | ||
3062 | sp->default_rcv_context = 0; | ||
3063 | |||
3019 | /* Initialize default setup parameters. These parameters | 3064 | /* Initialize default setup parameters. These parameters |
3020 | * can be modified with the SCTP_INITMSG socket option or | 3065 | * can be modified with the SCTP_INITMSG socket option or |
3021 | * overridden by the SCTP_INIT CMSG. | 3066 | * overridden by the SCTP_INIT CMSG. |
@@ -4421,6 +4466,42 @@ static int sctp_getsockopt_mappedv4(struct sock *sk, int len, | |||
4421 | } | 4466 | } |
4422 | 4467 | ||
4423 | /* | 4468 | /* |
4469 | * 7.1.29. Set or Get the default context (SCTP_CONTEXT) | ||
4470 | * (chapter and verse is quoted at sctp_setsockopt_context()) | ||
4471 | */ | ||
4472 | static int sctp_getsockopt_context(struct sock *sk, int len, | ||
4473 | char __user *optval, int __user *optlen) | ||
4474 | { | ||
4475 | struct sctp_assoc_value params; | ||
4476 | struct sctp_sock *sp; | ||
4477 | struct sctp_association *asoc; | ||
4478 | |||
4479 | if (len != sizeof(struct sctp_assoc_value)) | ||
4480 | return -EINVAL; | ||
4481 | |||
4482 | if (copy_from_user(¶ms, optval, len)) | ||
4483 | return -EFAULT; | ||
4484 | |||
4485 | sp = sctp_sk(sk); | ||
4486 | |||
4487 | if (params.assoc_id != 0) { | ||
4488 | asoc = sctp_id2assoc(sk, params.assoc_id); | ||
4489 | if (!asoc) | ||
4490 | return -EINVAL; | ||
4491 | params.assoc_value = asoc->default_rcv_context; | ||
4492 | } else { | ||
4493 | params.assoc_value = sp->default_rcv_context; | ||
4494 | } | ||
4495 | |||
4496 | if (put_user(len, optlen)) | ||
4497 | return -EFAULT; | ||
4498 | if (copy_to_user(optval, ¶ms, len)) | ||
4499 | return -EFAULT; | ||
4500 | |||
4501 | return 0; | ||
4502 | } | ||
4503 | |||
4504 | /* | ||
4424 | * 7.1.17 Set the maximum fragrmentation size (SCTP_MAXSEG) | 4505 | * 7.1.17 Set the maximum fragrmentation size (SCTP_MAXSEG) |
4425 | * | 4506 | * |
4426 | * This socket option specifies the maximum size to put in any outgoing | 4507 | * This socket option specifies the maximum size to put in any outgoing |
@@ -4558,6 +4639,9 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, | |||
4558 | retval = sctp_getsockopt_adaption_layer(sk, len, optval, | 4639 | retval = sctp_getsockopt_adaption_layer(sk, len, optval, |
4559 | optlen); | 4640 | optlen); |
4560 | break; | 4641 | break; |
4642 | case SCTP_CONTEXT: | ||
4643 | retval = sctp_getsockopt_context(sk, len, optval, optlen); | ||
4644 | break; | ||
4561 | default: | 4645 | default: |
4562 | retval = -ENOPROTOOPT; | 4646 | retval = -ENOPROTOOPT; |
4563 | break; | 4647 | break; |
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index e255a709f1b7..93ac63b055ba 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c | |||
@@ -849,8 +849,10 @@ void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, | |||
849 | */ | 849 | */ |
850 | sinfo.sinfo_assoc_id = sctp_assoc2id(event->asoc); | 850 | sinfo.sinfo_assoc_id = sctp_assoc2id(event->asoc); |
851 | 851 | ||
852 | /* context value that is set via SCTP_CONTEXT socket option. */ | ||
853 | sinfo.sinfo_context = event->asoc->default_rcv_context; | ||
854 | |||
852 | /* These fields are not used while receiving. */ | 855 | /* These fields are not used while receiving. */ |
853 | sinfo.sinfo_context = 0; | ||
854 | sinfo.sinfo_timetolive = 0; | 856 | sinfo.sinfo_timetolive = 0; |
855 | 857 | ||
856 | put_cmsg(msghdr, IPPROTO_SCTP, SCTP_SNDRCV, | 858 | put_cmsg(msghdr, IPPROTO_SCTP, SCTP_SNDRCV, |