/**
         * Creates a BindingResponse assigning the specified values to mandatory
         * headers.
         *
         * @param mappedAddress     the address to assign the mappedAddressAttribute
         * @param sourceAddress     the address to assign the sourceAddressAttribute
         * @param changedAddress    the address to assign the changedAddressAttribute
         * @return a BindingResponse assigning the specified values to mandatory
         *         headers.
         * @throws StunException ILLEGAL_ARGUMENT
         */
        public static Response CreateBindingResponse(StunAddress mappedAddress,
                                                     StunAddress sourceAddress,
                                                     StunAddress changedAddress)
        {
            Response bindingResponse = new Response();

            bindingResponse.SetMessageType(Message.BINDING_RESPONSE);

            //mapped address
            MappedAddressAttribute mappedAddressAttribute =
                AttributeFactory.CreateMappedAddressAttribute(mappedAddress);

            //source address
            SourceAddressAttribute sourceAddressAttribute =
                AttributeFactory.CreateSourceAddressAttribute(sourceAddress);

            //changed address
            ChangedAddressAttribute changedAddressAttribute =
                AttributeFactory.CreateChangedAddressAttribute(changedAddress);

            bindingResponse.AddAttribute(mappedAddressAttribute);
            bindingResponse.AddAttribute(sourceAddressAttribute);
            bindingResponse.AddAttribute(changedAddressAttribute);

            return(bindingResponse);
        }
Exemple #2
0
        //------------------------------------ SOURCE ADDRESS --------------------------

        /**
         * Creates a SourceFromAddressAttribute of the specified type and with
         * the specified address and port
         * @param address the address value of the address attribute
         * @return the newly created address attribute.
         */
        public static SourceAddressAttribute CreateSourceAddressAttribute(
            StunAddress address)
        {
            SourceAddressAttribute attribute = new SourceAddressAttribute();

            attribute.SetAddress(address);

            return(attribute);
        }
        /**
         * Decodes the specified binary array and returns the corresponding
         * attribute object.
         * @param bytes the binary array that should be decoded.
         * @param offset the index where the message starts.
         * @param length the number of bytes that the message is long.
         * @return An object representing the attribute encoded in bytes or null if
         *         the attribute was not recognized.
         * @throws StunException if bytes does is not a valid STUN attribute.
         */
        public static Attribute decode(byte[] bytes, int offset, int length)
        {
            if (bytes == null || bytes.Length < Attribute.HEADER_LENGTH)
            {
                throw new StunException(StunException.ILLEGAL_ARGUMENT,
                                        "Could not decode the specified binary array.");
            }

            //Discover attribute type
            int attributeTypec   = (int)(((bytes[offset] << 8) & 0xff00) | (bytes[offset + 1] & 0xff));
            int attributeType    = (int)attributeTypec;
            int attributeLengthc = (int)(((bytes[offset + 2] << 8) & 0xff00) | (bytes[offset + 3] & 0xff));
            int attributeLength  = (int)attributeLengthc;

            if (attributeLength > bytes.Length - offset)
            {
                throw new StunException(StunException.ILLEGAL_ARGUMENT,
                                        "The indicated attribute length (" + attributeLength + ") "
                                        + "does not match the length of the passed binary array");
            }

            Attribute decodedAttribute = null;

            switch (attributeType)
            {
            case Attribute.CHANGE_REQUEST:
                decodedAttribute = new ChangeRequestAttribute(); break;

            case Attribute.CHANGED_ADDRESS:
                decodedAttribute = new ChangedAddressAttribute(); break;

            case Attribute.MAPPED_ADDRESS:
                decodedAttribute = new MappedAddressAttribute(); break;

            case Attribute.ERROR_CODE:
                decodedAttribute = new ErrorCodeAttribute(); break;

            case Attribute.MESSAGE_INTEGRITY:
                throw new StunException(
                          "The MESSAGE-INTEGRITY Attribute is not yet implemented.");

            case Attribute.PASSWORD:
                throw new StunException(
                          "The PASSWORD Attribute is not yet implemented.");

            case Attribute.REFLECTED_FROM:
                decodedAttribute = new ReflectedFromAttribute(); break;

            case Attribute.RESPONSE_ADDRESS:
                decodedAttribute = new ResponseAddressAttribute(); break;

            case Attribute.SOURCE_ADDRESS:
                decodedAttribute = new SourceAddressAttribute(); break;

            case Attribute.UNKNOWN_ATTRIBUTES:
                decodedAttribute = new UnknownAttributesAttribute(); break;

            case Attribute.USERNAME:
                throw new StunException(
                          "The USERNAME Attribute is not yet implemented.");

            //According to rfc3489 we should silently ignore unknown attributes.
            default:
                decodedAttribute = new UnknownAttributesAttribute(); break;
                //return null;
            }

            decodedAttribute.SetAttributeType(attributeType);

            decodedAttribute.DecodeAttributeBody(bytes, (Attribute.HEADER_LENGTH + offset), attributeLength);

            return(decodedAttribute);
        }