Example #1
0
        /**
         * Creates a listening point for the specified socket and attempts to
         * discover how its local address is NAT mapped.
         * @param socket the socket whose address needs to be resolved.
         * @return a StunAddress object containing the mapped address or null if
         * discovery failed.
         * @throws StunException if something fails along the way.
         */

        public virtual StunAddress GetMappingFor(MyUdpClient socket)
        {
            NetAccessPointDescriptor apDesc = stunStack.InstallNetAccessPoint(socket);

            requestSender = new BlockingRequestSender(stunProvider, apDesc);
            StunMessageEvent evt = null;

            try
            {
                evt = requestSender.SendRequestAndWaitForResponse(
                    MessageFactory.CreateBindingRequest(), serverAddress);
            }
            finally
            {
                stunStack.RemoveNetAccessPoint(apDesc);
            }

            if (evt != null)
            {
                Response res = (Response)evt.GetMessage();
                MappedAddressAttribute maAtt =
                    (MappedAddressAttribute)
                    res.GetAttribute(Attribute.MAPPED_ADDRESS);
                if (maAtt != null)
                {
                    return(maAtt.GetAddress());
                }
            }

            return(null);
        }
Example #2
0
        /**
         * Creates a listening point from the following address and attempts to
         * discover how it is mapped so that using inside the application is possible.
         * @param address the [address]:[port] pair where ther request should be
         * sent from.
         * @return a StunAddress object containing the mapped address or null if
         * discovery failed.
         * @throws StunException if something fails along the way.
         */
        public virtual StunAddress GetMappingFor(StunAddress address)
        {
            NetAccessPointDescriptor apDesc = new NetAccessPointDescriptor(address);

            stunStack.InstallNetAccessPoint(apDesc);

            requestSender = new BlockingRequestSender(stunProvider, apDesc);
            StunMessageEvent evt = null;

            try
            {
                evt = requestSender.SendRequestAndWaitForResponse(
                    MessageFactory.CreateBindingRequest(), serverAddress);
            }
            finally
            {
                //free the port to allow the application to use it.
                stunStack.RemoveNetAccessPoint(apDesc);
            }

            if (evt != null)
            {
                Response res = (Response)evt.GetMessage();
                MappedAddressAttribute maAtt =
                    (MappedAddressAttribute)
                    res.GetAttribute(Attribute.MAPPED_ADDRESS);
                if (maAtt != null)
                {
                    StunAddress sa = maAtt.GetAddress();
                    return(sa);
                }
            }

            return(null);
        }
Example #3
0
        /**
         * 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);
        }
Example #4
0
        //------------------------------------ MAPPED ADDRESS --------------------------

        /**
         * Creates a MappedAddressAttribute 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 MappedAddressAttribute CreateMappedAddressAttribute(
            StunAddress address)
        {
            MappedAddressAttribute attribute = new MappedAddressAttribute();

            attribute.SetAddress(address);

            return(attribute);
        }
Example #5
0
        //------------------------------------ MAPPED ADDRESS --------------------------
        /**
         * Creates a MappedAddressAttribute 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 MappedAddressAttribute CreateMappedAddressAttribute(
			StunAddress address)
        {
            MappedAddressAttribute attribute = new MappedAddressAttribute();

            attribute.SetAddress(address);

            return attribute;
        }
Example #6
0
        /**
         * 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;
        }
Example #7
0
        /**
         * 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);
        }