1 /*
   2  * Copyright (c) 2009, 2012, 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      */
  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      */
  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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 302     public abstract MessageInfo timeToLive(long millis);
 303 }