⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 message.java

📁 stun的java实现
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * Stun4j, the OpenSource Java Solution for NAT and Firewall Traversal.
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package net.java.stun4j.message;

import net.java.stun4j.attribute.Attribute;
import java.util.*;
import net.java.stun4j.StunException;
import net.java.stun4j.attribute.ChangeRequestAttribute;
import net.java.stun4j.attribute.AttributeDecoder;

/**
 * This class represents a STUN message. STUN messages are TLV (type-length-value)
 * encoded using big endian (network ordered) binary.  All STUN messages start
 * with a STUN header, followed by a STUN payload.  The payload is a series of
 * STUN attributes, the set of which depends on the message type.  The STUN
 * header contains a STUN message type, transaction ID, and length.
 *
 * <p>Organisation: Louis Pasteur University, Strasbourg, France</p>
 * 					<p>Network Research Team (http://www-r2.u-strasbg.fr)</p>
 * @author Emil Ivov
 * @version 0.1
 */

public abstract class Message
{
    public static final char BINDING_REQUEST               = 0x0001;
    public static final char BINDING_RESPONSE              = 0x0101;
    public static final char BINDING_ERROR_RESPONSE        = 0x0111;
    public static final char SHARED_SECRET_REQUEST         = 0x0002;
    public static final char SHARED_SECRET_RESPONSE        = 0x0102;
    public static final char SHARED_SECRET_ERROR_RESPONSE  = 0x0112;

    //Message fields
    /**
     * The length of Stun Message Headers in byres
     * = len(Type) + len(DataLength) + len(Transaction ID).
     */
    public static final byte HEADER_LENGTH = 20;

    /**
     * Indicates the type of the message. The message type can be Binding Request,
     * Binding Response, Binding Error Response, Shared Secret Request, Shared
     * Secret Response, or Shared Secret Error Response.
     */
    protected char messageType = 0x0000;

    /**
     * The transaction ID is used to correlate requests and responses.
     */
    protected byte[] transactionID = null;

    /**
     * The length of the transaction id (in bytes).
     */
    public static final byte TRANSACTION_ID_LENGTH = 16;


    /**
     * The list of attributes contained by the message. We are using a hastable
     * rather than a uni-dimensional list, in order to facilitate attribute
     * search (even though it introduces some redundancies). Order is important
     * so we'll be using a LinkedHashMap
     */
    //not sure this is the best solution but I'm trying to keep entry order
    protected LinkedHashMap attributes = new LinkedHashMap();

    /**
     * Desribes which attributes are present in which messages.  An
     * M indicates that inclusion of the attribute in the message is
     * mandatory, O means its optional, C means it's conditional based on
     * some other aspect of the message, and N/A means that the attribute is
     * not applicable to that message type.
     *
     *
     *                                         Binding  Shared  Shared  Shared        <br/>
     *                       Binding  Binding  Error    Secret  Secret  Secret        <br/>
     *   Att.                Req.     Resp.    Resp.    Req.    Resp.   Error         <br/>
     *                                                                  Resp.         <br/>
     *   _____________________________________________________________________        <br/>
     *   MAPPED-ADDRESS      N/A      M        N/A      N/A     N/A     N/A           <br/>
     *   RESPONSE-ADDRESS    O        N/A      N/A      N/A     N/A     N/A           <br/>
     *   CHANGE-REQUEST      O        N/A      N/A      N/A     N/A     N/A           <br/>
     *   SOURCE-ADDRESS      N/A      M        N/A      N/A     N/A     N/A           <br/>
     *   CHANGED-ADDRESS     N/A      M        N/A      N/A     N/A     N/A           <br/>
     *   USERNAME            O        N/A      N/A      N/A     M       N/A           <br/>
     *   PASSWORD            N/A      N/A      N/A      N/A     M       N/A           <br/>
     *   MESSAGE-INTEGRITY   O        O        N/A      N/A     N/A     N/A           <br/>
     *   ERROR-CODE          N/A      N/A      M        N/A     N/A     M             <br/>
     *   UNKNOWN-ATTRIBUTES  N/A      N/A      C        N/A     N/A     C             <br/>
     *   REFLECTED-FROM      N/A      C        N/A      N/A     N/A     N/A           <br/>
     *   XOR-MAPPED-ADDRESS  N/A      M        N/A      N/A     N/A     N/A
     *   XOR-ONLY            O        N/A      N/A      N/A     N/A     N/A
     *   SERVER              N/A      O        O        N/A     O       O
     *
     */
    public static final byte N_A = 0;
    public static final byte C   = 1;
    public static final byte O   = 2;
    public static final byte M   = 3;

    //Message indices
    protected static final byte BINDING_REQUEST_PRESENTITY_INDEX              = 0;
    protected static final byte BINDING_RESPONSE_PRESENTITY_INDEX             = 1;
    protected static final byte BINDING_ERROR_RESPONSE_PRESENTITY_INDEX       = 2;
    protected static final byte SHARED_SECRET_REQUEST_PRESENTITY_INDEX        = 3;
    protected static final byte SHARED_SECRET_RESPONSE_PRESENTITY_INDEX       = 4;
    protected static final byte SHARED_SECRET_ERROR_RESPONSE_PRESENTITY_INDEX = 5;

    //Attribute indices
    protected static final byte MAPPED_ADDRESS_PRESENTITY_INDEX               =  0;
    protected static final byte RESPONSE_ADDRESS_PRESENTITY_INDEX             =  1;
    protected static final byte CHANGE_REQUEST_PRESENTITY_INDEX               =  2;
    protected static final byte SOURCE_ADDRESS_PRESENTITY_INDEX               =  3;
    protected static final byte CHANGED_ADDRESS_PRESENTITY_INDEX              =  4;
    protected static final byte USERNAME_PRESENTITY_INDEX                     =  5;
    protected static final byte PASSWORD_PRESENTITY_INDEX                     =  6;
    protected static final byte MESSAGE_INTEGRITY_PRESENTITY_INDEX            =  7;
    protected static final byte ERROR_CODE_PRESENTITY_INDEX                   =  8;
    protected static final byte UNKNOWN_ATTRIBUTES_PRESENTITY_INDEX           =  9;
    protected static final byte REFLECTED_FROM_PRESENTITY_INDEX               = 10;
    protected static final byte XOR_MAPPED_ADDRESS_PRESENTITY_INDEX           = 11;
    protected static final byte XOR_ONLY_PRESENTITY_INDEX                     = 12;
    protected static final byte SERVER_PRESENTITY_INDEX                       = 13;
    protected static final byte UNKNOWN_OPTIONAL_ATTRIBUTES_PRESENTITY_INDEX  = 14;


    protected final static byte attributePresentities[][] = new byte[][]{
    //                                            Binding   Shared   Shared   Shared
    //                        Binding   Binding   Error     Secret   Secret   Secret
    //  Att.                  Req.      Resp.     Resp.     Req.     Resp.    Error
    //                                                                        Resp.
    //  _______________________________________________________________________
      /*MAPPED-ADDRESS*/    { N_A,      M,        N_A,      N_A,     N_A,     N_A},
      /*RESPONSE-ADDRESS*/  { O,        N_A,      N_A,      N_A,     N_A,     N_A},
      /*CHANGE-REQUEST*/    { O,        N_A,      N_A,      N_A,     N_A,     N_A},
      /*SOURCE-ADDRESS*/    { N_A,      M,        N_A,      N_A,     N_A,     N_A},
      /*CHANGED-ADDRESS*/   { N_A,      M,        N_A,      N_A,     N_A,     N_A},
      /*USERNAME*/          { O,        N_A,      N_A,      N_A,     M,       N_A},
      /*PASSWORD*/          { N_A,      N_A,      N_A,      N_A,     M,       N_A},
      /*MESSAGE-INTEGRITY*/ { O,        O,        N_A,      N_A,     N_A,     N_A},
      /*ERROR-CODE*/        { N_A,      N_A,      M,        N_A,     N_A,     M},
      /*UNKNOWN-ATTRIBUTES*/{ N_A,      N_A,      C,        N_A,     N_A,     C},
      /*REFLECTED-FROM*/    { N_A,      C,        N_A,      N_A,     N_A,     N_A},
      /*XOR-MAPPED-ADDRESS*/{ N_A,      M,        N_A,      N_A,     N_A,     N_A},
      /*XOR-ONLY*/          { O,        N_A,      N_A,      N_A,     N_A,     N_A},
      /*SERVER*/            { N_A,      O,        O,        N_A,     O,       O},
      /*UNKNOWN_OPTIONAL*/  { O,        O,        O,        O,       O,       O}};




    /**
     * Creates an empty STUN Mesage.
     */
    protected Message()
    {
    }

    /**
     * Returns the length of this message's body.
     * @return the length of the data in this message.
     */
    public char getDataLength()
    {
        char length = 0;
        Attribute att = null;

        Iterator iter = attributes.entrySet().iterator();
        while (iter.hasNext()) {
            att = (Attribute)((Map.Entry)iter.next()).getValue();
            length += att.getDataLength() + Attribute.HEADER_LENGTH;
        }

        return length;
    }

    /**
     * Adds the specified attribute to this message. If an attribute with that
     * name was already added, it would be replaced.
     * @param attribute the attribute to add to this message.
     * @throws StunException if the message cannot contain
     * such an attribute.
     */
    public void addAttribute(Attribute attribute)
        throws StunException
    {
        Character attributeType = new Character(attribute.getAttributeType());

        if (getAttributePresentity(attributeType.charValue()) == N_A)
            throw new StunException(StunException.ILLEGAL_ARGUMENT,
                                    "The attribute "
                                    + attribute.getName()
                                    + " is not allowed in a "
                                    + getName());

        attributes.put(attributeType, attribute);
    }

    /**
     * Returns the attribute with the specified type or null if no such
     * attribute exists.
     *
     * @param attributeType the type of the attribute
     * @return the attribute with the specified type or null if no such attribute
     * exists
     */
    public Attribute getAttribute(char attributeType)
    {
        return (Attribute)attributes.get(new Character(attributeType));
    }

    /*
     * Returns an enumeration containing all message attributes.
     * @return an enumeration containing all message attributes..
     */
    /*
    public Iterator getAttributes()
    {
        return attributes.entrySet().iterator();
    }
    */

    /**
     * Removes the specified attribute.
     * @param attributeType the attribute to remove.
     */
    public void removeAttribute(char attributeType)
    {
        attributes.remove(new Character(attributeType));
    }

    /**
     * Returns the number of attributes, currently contained by the message.
     * @return the number of attributes, currently contained by the message.
     */
    public int getAttributeCount()
    {
        return  attributes.size();
    }



    /**
     * Sets this message's type to be messageType. Method is package access
     * as it should not permit changing the type of message once it has been
     * initialized (could provoke attribute discrepancies). Called by
     * messageFactory.
     * @param messageType the message type.
     * @throws StunException ILLEGAL_ARGUMENT if message type is not valid in
     * the current context (e.g. when trying to set a Response type to a Request
     * and vice versa)
     */
    protected void setMessageType(char messageType)
        throws StunException
    {
        this.messageType = messageType;
    }

    /**
     * The message type of this message.
     * @return the message type of the message.
     */
    public char getMessageType()
    {
        return messageType;
    }

    /**
     * Copies the specified tranID and sets it as this message's transactionID.
     * @param tranID the transaction id to set in this message.
     * @throws StunException ILLEGAL_ARGUMENT if the transaction id is not valid.
     */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -