1 /*
2  * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 package com.sun.nio.sctp;
26 
27 import java.net.SocketAddress;
28 
29 /**
30  * The {@code MessageInfo} class provides additional ancillary information about
31  * messages.
32  *
33  * <P> Received SCTP messages, returned by
34  * {@link SctpChannel#receive SctpChannel.receive} and {@link
35  * SctpMultiChannel#receive SctpMultiChannel.receive},
36  * return a {@code MessageInfo} instance that can be queried to determine
37  * ancillary information about the received message. Messages being sent should
38  * use one of the {@link #createOutgoing(java.net.SocketAddress,int)
39  * createOutgoing} methods to provide ancillary data for the message being
40  * sent, and may use the appropriate setter methods to override the default
41  * values provided for {@link #isUnordered() unordered}, {@link #timeToLive()
42  * timeToLive}, {@link #isComplete() complete} and {@link #payloadProtocolID()
43  * payloadProtocolID}, before sending the message.
44  *
45  * <P> For out going messages the {@code timeToLive} parameter is a time period
46  * that the sending side SCTP stack may expire the message if it has not been
47  * sent. This time period is an indication to the stack that the message is no
48  * longer required to be sent after the time period expires. It is not a hard
49  * timeout and may be influenced by whether the association supports the partial
50  * reliability extension, <a href=http://www.ietf.org/rfc/rfc3758.txt>RFC 3758
51  * </a>.
52  *
53  * <P> {@code MessageInfo} instances are not safe for use by multiple concurrent
54  * threads. If a MessageInfo is to be used by more than one thread then access
55  * to the MessageInfo should be controlled by appropriate synchronization.
56  *
57  * @since 1.7
58  */
59 public abstract class MessageInfo {
60     /**
61      * Initializes a new instance of this class.
62      */
MessageInfo()63     protected MessageInfo() {}
64 
65     /**
66      * Creates a {@code MessageInfo} instance suitable for use when
67      * sending a message.
68      *
69      * <P> The returned instance will have its {@link #isUnordered() unordered}
70      * value set to {@code false}, its {@link #timeToLive() timeToLive} value
71      * set to {@code 0}, its {@link #isComplete() complete} value set
72      * to {@code true}, and its {@link #payloadProtocolID() payloadProtocolID}
73      * value set to {@code 0}. These values, if required, can be set through
74      * the appropriate setter method before sending the message.
75      *
76      * @param  address
77      *         For a connected {@code SctpChannel} the address is the
78      *         preferred peer address of the association to send the message
79      *         to, or {@code null} to use the peer primary address. For an
80      *         {@code SctpMultiChannel} the address is used to determine
81      *         the association, or if no association exists with a peer of that
82      *         address then one is setup.
83      *
84      * @param  streamNumber
85      *         The stream number that the message will be sent on
86      *
87      * @return  The outgoing message info
88      *
89      * @throws  IllegalArgumentException
90      *          If the streamNumber is negative or greater than {@code 65536}
91      */
createOutgoing(SocketAddress address, int streamNumber)92     public static MessageInfo createOutgoing(SocketAddress address,
93                                              int streamNumber) {
94         if (streamNumber < 0 || streamNumber > 65536)
95             throw new IllegalArgumentException("Invalid stream number");
96 
97         return new sun.nio.ch.sctp.MessageInfoImpl(null, address, streamNumber);
98     }
99     /**
100      * Creates a {@code MessageInfo} instance suitable for use when
101      * sending a message to a given association. Typically used for
102      * {@code SctpMultiChannel} when an association has already been setup.
103      *
104      * <P> The returned instance will have its {@link #isUnordered() unordered}
105      * value set to {@code false}, its {@link #timeToLive() timeToLive} value
106      * set to {@code 0}, its {@link #isComplete() complete} value set
107      * to {@code true}, and its {@link #payloadProtocolID() payloadProtocolID}
108      * value set to {@code 0}. These values, if required, can be set through
109      * the appropriate setter method before sending the message.
110      *
111      * @param  association
112      *         The association to send the message on
113      *
114      * @param  address
115      *         The preferred peer address of the association to send the message
116      *         to, or {@code null} to use the peer primary address
117      *
118      * @param  streamNumber
119      *         The stream number that the message will be sent on.
120      *
121      * @return  The outgoing message info
122      *
123      * @throws  IllegalArgumentException
124      *          If {@code association} is {@code null}, or the streamNumber is
125      *          negative or greater than {@code 65536}
126      */
createOutgoing(Association association, SocketAddress address, int streamNumber)127     public static MessageInfo createOutgoing(Association association,
128                                              SocketAddress address,
129                                              int streamNumber) {
130         if (association == null)
131             throw new IllegalArgumentException("association cannot be null");
132 
133         if (streamNumber < 0 || streamNumber > 65536)
134             throw new IllegalArgumentException("Invalid stream number");
135 
136         return new sun.nio.ch.sctp.MessageInfoImpl(association,
137                                                    address, streamNumber);
138     }
139 
140     /**
141      * Returns the source socket address if the message has been received,
142      * otherwise the preferred destination of the message to be sent.
143      *
144      * @return  The socket address, or {@code null} if this instance is to be
145      *          used for sending a message and has been construced without
146      *          specifying a preferred destination address
147      *
148      */
address()149     public abstract SocketAddress address();
150 
151     /**
152      * Returns the association that the message was received on, if the message
153      * has been received, otherwise the association that the message is to be
154      * sent on.
155      *
156      * @return The association, or {@code null} if this instance is to be
157      *         used for sending a message and has been construced using the
158      *         the {@link #createOutgoing(SocketAddress,int)
159      *         createOutgoing(SocketAddress,int)} static factory method
160      */
association()161     public abstract Association association();
162 
163     /**
164      * Returns the number of bytes read for the received message.
165      *
166      * <P> This method is only appicable for received messages, it has no
167      * meaning for messages being sent.
168      *
169      * @return  The number of bytes read, {@code -1} if the channel is an {@link
170      *          SctpChannel} that has reached end-of-stream, otherwise
171      *          {@code 0}
172      */
bytes()173     public abstract int bytes();
174 
175     /**
176      * Tells whether or not the message is complete.
177      *
178      * <P> For received messages {@code true} indicates that the message was
179      * completely received. For messages being sent {@code true} indicates that
180      * the message is complete, {@code false} indicates that the message is not
181      * complete. How the send channel interprets this value depends on the value
182      * of its {@link SctpStandardSocketOptions#SCTP_EXPLICIT_COMPLETE
183      * SCTP_EXPLICIT_COMPLETE} socket option.
184      *
185      * @return  {@code true} if, and only if, the message is complete
186      */
isComplete()187     public abstract boolean isComplete();
188 
189     /**
190      * Sets whether or not the message is complete.
191      *
192      * <P> For messages being sent {@code true} indicates that
193      * the message is complete, {@code false} indicates that the message is not
194      * complete. How the send channel interprets this value depends on the value
195      * of its {@link SctpStandardSocketOptions#SCTP_EXPLICIT_COMPLETE
196      * SCTP_EXPLICIT_COMPLETE} socket option.
197      *
198      * @param  complete
199      *         {@code true} if, and only if, the message is complete
200      *
201      * @return  This MessageInfo
202      *
203      * @see  MessageInfo#isComplete()
204      */
complete(boolean complete)205     public abstract MessageInfo complete(boolean complete);
206 
207     /**
208      * Tells whether or not the message is unordered. For received messages
209      * {@code true} indicates that the message was sent non-ordered. For
210      * messages being sent {@code true} requests the un-ordered delivery of the
211      * message, {@code false} indicates that the message is ordered.
212      *
213      * @return  {@code true} if the message is unordered, otherwise
214      *          {@code false}
215      */
isUnordered()216     public abstract boolean isUnordered();
217 
218     /**
219      * Sets whether or not the message is unordered.
220      *
221      * @param  unordered
222      *         {@code true} requests the un-ordered delivery of the message,
223      *         {@code false} indicates that the message is ordered.
224      *
225      * @return  This MessageInfo
226      *
227      * @see  MessageInfo#isUnordered()
228      */
unordered(boolean unordered)229     public abstract MessageInfo unordered(boolean unordered);
230 
231     /**
232      * Returns the payload protocol Identifier.
233      *
234      * <P> A value indicating the type of payload protocol data being
235      * transmitted/received. This value is passed as opaque data by SCTP.
236      * {@code 0} indicates an unspecified payload protocol identifier.
237      *
238      * @return  The Payload Protocol Identifier
239      */
payloadProtocolID()240     public abstract int payloadProtocolID();
241 
242     /**
243      * Sets the payload protocol Identifier.
244      *
245      * <P> A value indicating the type of payload protocol data being
246      * transmitted. This value is passed as opaque data by SCTP.
247      *
248      * @param  ppid
249      *         The Payload Protocol Identifier, or {@code 0} indicate an
250      *         unspecified payload protocol identifier.
251      *
252      * @return  This MessageInfo
253      *
254      * @see  MessageInfo#payloadProtocolID()
255      */
payloadProtocolID(int ppid)256     public abstract MessageInfo payloadProtocolID(int ppid);
257 
258     /**
259      * Returns the stream number that the message was received on, if the
260      * message has been received, otherwise the stream number that the message
261      * is to be sent on.
262      *
263      * @return  The stream number
264      */
streamNumber()265     public abstract int streamNumber();
266 
267     /**
268      * Sets the stream number that the message is to be sent on.
269      *
270      * @param  streamNumber
271      *         The stream number
272      *
273      * @throws  IllegalArgumentException
274      *          If the streamNumber is negative or greater than {@code 65536}
275      *
276      * @return  This MessageInfo
277      */
streamNumber(int streamNumber)278     public abstract MessageInfo streamNumber(int streamNumber);
279 
280     /**
281      * The time period that the sending side may expire the message if it has
282      * not been sent, or {@code 0} to indicate that no timeout should occur. This
283      * value is only applicable for messages being sent, it has no meaning for
284      * received messages.
285      *
286      * @return  The time period in milliseconds, or {@code 0}
287      */
timeToLive()288     public abstract long timeToLive();
289 
290     /**
291      * Sets the time period that the sending side may expire the message if it
292      * has not been sent.
293      *
294      * @param  millis
295      *         The time period in milliseconds, or {@code 0} to indicate that no
296      *         timeout should occur
297      *
298      * @return  This MessageInfo
299      *
300      * @see MessageInfo#timeToLive()
301      */
timeToLive(long millis)302     public abstract MessageInfo timeToLive(long millis);
303 }
304