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

Commit 6ab792f5 authored by Ivan Skytte Jorgensen's avatar Ivan Skytte Jorgensen Committed by David S. Miller
Browse files

[SCTP]: Add support for SCTP_CONTEXT socket option.

parent 882a382c
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -275,6 +275,7 @@ struct sctp_sock {
	__u16 default_flags;
	__u32 default_context;
	__u32 default_timetolive;
	__u32 default_rcv_context;

	/* Heartbeat interval: The endpoint sends out a Heartbeat chunk to
	 * the destination address every heartbeat interval. This value
@@ -1657,6 +1658,9 @@ struct sctp_association {
	__u32 default_context;
	__u32 default_timetolive;

	/* Default receive parameters */
	__u32 default_rcv_context;

	/* This tracks outbound ssn for a given stream.	 */
	struct sctp_ssnmap *ssnmap;

+2 −0
Original line number Diff line number Diff line
@@ -95,6 +95,8 @@ enum sctp_optname {
#define SCTP_GET_PEER_ADDR_INFO SCTP_GET_PEER_ADDR_INFO
	SCTP_DELAYED_ACK_TIME,
#define SCTP_DELAYED_ACK_TIME SCTP_DELAYED_ACK_TIME
	SCTP_CONTEXT,	/* Receive Context */
#define SCTP_CONTEXT SCTP_CONTEXT

	/* Internal Socket Options. Some of the sctp library functions are 
	 * implemented using these socket options.
+1 −0
Original line number Diff line number Diff line
@@ -298,6 +298,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
	asoc->default_flags = sp->default_flags;
	asoc->default_context = sp->default_context;
	asoc->default_timetolive = sp->default_timetolive;
	asoc->default_rcv_context = sp->default_rcv_context;

	return asoc;

+84 −0
Original line number Diff line number Diff line
@@ -2746,6 +2746,46 @@ static int sctp_setsockopt_adaption_layer(struct sock *sk, char __user *optval,
	return 0;
}

/*
 * 7.1.29.  Set or Get the default context (SCTP_CONTEXT)
 *
 * The context field in the sctp_sndrcvinfo structure is normally only
 * used when a failed message is retrieved holding the value that was
 * sent down on the actual send call.  This option allows the setting of
 * a default context on an association basis that will be received on
 * reading messages from the peer.  This is especially helpful in the
 * one-2-many model for an application to keep some reference to an
 * internal state machine that is processing messages on the
 * association.  Note that the setting of this value only effects
 * received messages from the peer and does not effect the value that is
 * saved with outbound messages.
 */
static int sctp_setsockopt_context(struct sock *sk, char __user *optval,
				   int optlen)
{
	struct sctp_assoc_value params;
	struct sctp_sock *sp;
	struct sctp_association *asoc;

	if (optlen != sizeof(struct sctp_assoc_value))
		return -EINVAL;
	if (copy_from_user(&params, optval, optlen))
		return -EFAULT;

	sp = sctp_sk(sk);

	if (params.assoc_id != 0) {
		asoc = sctp_id2assoc(sk, params.assoc_id);
		if (!asoc)
			return -EINVAL;
		asoc->default_rcv_context = params.assoc_value;
	} else {
		sp->default_rcv_context = params.assoc_value;
	}

	return 0;
}

/* API 6.2 setsockopt(), getsockopt()
 *
 * 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,
	case SCTP_ADAPTION_LAYER:
		retval = sctp_setsockopt_adaption_layer(sk, optval, optlen);
		break;
	case SCTP_CONTEXT:
		retval = sctp_setsockopt_context(sk, optval, optlen);
		break;

	default:
		retval = -ENOPROTOOPT;
@@ -3016,6 +3059,8 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
	sp->default_context = 0;
	sp->default_timetolive = 0;

	sp->default_rcv_context = 0;

	/* Initialize default setup parameters. These parameters
	 * can be modified with the SCTP_INITMSG socket option or
	 * overridden by the SCTP_INIT CMSG.
@@ -4420,6 +4465,42 @@ static int sctp_getsockopt_mappedv4(struct sock *sk, int len,
	return 0;
}

/*
 * 7.1.29.  Set or Get the default context (SCTP_CONTEXT)
 * (chapter and verse is quoted at sctp_setsockopt_context())
 */
static int sctp_getsockopt_context(struct sock *sk, int len,
				   char __user *optval, int __user *optlen)
{
	struct sctp_assoc_value params;
	struct sctp_sock *sp;
	struct sctp_association *asoc;

	if (len != sizeof(struct sctp_assoc_value))
		return -EINVAL;

	if (copy_from_user(&params, optval, len))
		return -EFAULT;

	sp = sctp_sk(sk);

	if (params.assoc_id != 0) {
		asoc = sctp_id2assoc(sk, params.assoc_id);
		if (!asoc)
			return -EINVAL;
		params.assoc_value = asoc->default_rcv_context;
	} else {
		params.assoc_value = sp->default_rcv_context;
	}

	if (put_user(len, optlen))
		return -EFAULT;
	if (copy_to_user(optval, &params, len))
		return -EFAULT;

	return 0;
}

/*
 * 7.1.17 Set the maximum fragrmentation size (SCTP_MAXSEG)
 *
@@ -4558,6 +4639,9 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
		retval = sctp_getsockopt_adaption_layer(sk, len, optval,
							optlen);
		break;
	case SCTP_CONTEXT:
		retval = sctp_getsockopt_context(sk, len, optval, optlen);
		break;
	default:
		retval = -ENOPROTOOPT;
		break;
+3 −1
Original line number Diff line number Diff line
@@ -849,8 +849,10 @@ void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
	 */
	sinfo.sinfo_assoc_id = sctp_assoc2id(event->asoc);

	/* context value that is set via SCTP_CONTEXT socket option. */
	sinfo.sinfo_context = event->asoc->default_rcv_context;

	/* These fields are not used while receiving. */
	sinfo.sinfo_context = 0;
	sinfo.sinfo_timetolive = 0;

	put_cmsg(msghdr, IPPROTO_SCTP, SCTP_SNDRCV,