/**
         * Creates a client transaction
         * @param providerCallback the provider that created us.
         * @param request the request that we are living for.
         * @param requestDestination the destination of the request.
         * @param apDescriptor the access point through which we are supposed to
         * @param responseCollector the instance that should receive this request's
         * response.
         * retransmit.
         */
        public StunClientTransaction(StunProvider            providerCallback,
			Request                  request,
			StunAddress              requestDestination,
			NetAccessPointDescriptor apDescriptor,
			ResponseCollector        responseCollector)
        {
            this.providerCallback  = providerCallback;
            this.request           = request;
            this.apDescriptor      = apDescriptor;
            this.responseCollector = responseCollector;
            this.requestDestination = requestDestination;

            this.transactionID = TransactionID.CreateTransactionID();

            request.SetTransactionID(transactionID.GetTransactionID());

            runningThread = new Thread(new ThreadStart(this.Run));
        }
示例#2
0
        /**
         * Creates a default binding request. The request contains a ChangeReqeust
         * attribute with zero change ip and change port flags.
         * @return a default binding request.
         */
        public static Request CreateBindingRequest()
        {
            Request bindingRequest = new Request();
            try
            {
                bindingRequest.SetMessageType(Message.BINDING_REQUEST);
            }
            catch (StunException ex)
            {
                //there should be no exc here since we're the creators.
                Console.WriteLine("Exception {0} {1}", ex.Message, ex.StackTrace);
            }

            //add a change request attribute
            ChangeRequestAttribute attribute
                = AttributeFactory.CreateChangeRequestAttribute();

            bindingRequest.AddAttribute(attribute);

            return bindingRequest;
        }
示例#3
0
        /**
         * Sends the specified request through the specified access point, and
         * registers the specified ResponseCollector for later notification.
         * @param  request     the request to send
         * @param  sendTo      the destination address of the request.
         * @param  sendThrough the access point to use when sending the request
         * @param  collector   the instance to notify when a response arrives or the
         *                     the transaction timeouts
         * @throws StunException
         * ILLEGAL_STATE if the stun stack is not started. <br/>
         * ILLEGAL_ARGUMENT if the apDescriptor references an access point that had
         * not been installed <br/>
         * NETWORK_ERROR if an error occurs while sending message bytes through the
         * network socket. <br/>

         */
        public virtual void SendRequest( Request                  request,
			StunAddress              sendTo,
			NetAccessPointDescriptor sendThrough,
			ResponseCollector        collector )
        {
            stunStack.CheckStarted();

            StunClientTransaction clientTransaction =
                new StunClientTransaction(this,
                request,
                sendTo,
                sendThrough,
                collector);

            clientTransactions[clientTransaction.GetTransactionID()] =
                clientTransaction;
            clientTransaction.SendRequest();
        }
        /**
         * Sends the specified request and blocks until a response has been
         * received or the request transaction has timed out.
         * @param request the reuqest to send
         * @param serverAddress the request destination address
         * @return the event encapsulating the response or null if no response
         * has been received.
         * @throws StunException NETWORK_ERROR or other if we fail to send
         * the message
         */
        public virtual StunMessageEvent SendRequestAndWaitForResponse(
			Request request,
			StunAddress serverAddress)
        {
            Monitor.Enter(this);
            try

            {
                stunProvider.SendRequest(request, serverAddress, apDescriptor,
                    this);

                Monitor.Wait(this);

                StunMessageEvent res = responseEvent;
                responseEvent = null; //prepare for next message

                return res;
            }
            finally
            {
                Monitor.Exit(this);
            }
        }
示例#5
0
        /**
         * Constructs a message from its binary representation.
         * @param binMessage the binary array that contains the encoded message
         * @param offset the index where the message starts.
         * @param arrayLen the length of the message
         * @return a Message object constructed from the binMessage array
         * @throws StunException ILLEGAL_ARGUMENT if one or more of the arguments
         * have invalid values.
         */
        public static Message Decode(byte[] binMessage, int offset, int arrayLen)
        {
            arrayLen = Math.Min(binMessage.Length, arrayLen);

            if(binMessage == null || arrayLen - offset < Message.HEADER_LENGTH)
                throw new StunException(StunException.ILLEGAL_ARGUMENT,
                    "The given binary array is not a valid StunMessage");

            int messageType = (int)(((binMessage[offset++]<<8) & 0xff00) | (binMessage[offset++]&0xFF));
            int mti = (int) messageType;

            Message message;
            if (Message.IsResponseType(messageType))
            {
                message = new Response();
            }
            else
            {
                message = new Request();
            }
            message.SetMessageType(messageType);

            int length = (int)(((binMessage[offset++]<<8) & 0xff00) | (binMessage[offset++]&0xFF));

            if(arrayLen - offset - TRANSACTION_ID_LENGTH < length)
                throw new StunException(StunException.ILLEGAL_ARGUMENT,
                    "The given binary array does not seem to "
                    +"contain a whole StunMessage");

            byte[] tranID = new byte[TRANSACTION_ID_LENGTH];
            for (int x = 0; x < TRANSACTION_ID_LENGTH; x++)
            {
                tranID[x] = binMessage[offset + x];
            }

            message.SetTransactionID(tranID);
            offset+=TRANSACTION_ID_LENGTH;

            while(offset - Message.HEADER_LENGTH< length)
            {
                Attribute att = AttributeDecoder.decode(binMessage,
                    offset,
                    (length - offset));
                if (att != null)
                {
                    message.AddAttribute(att);
                    offset += att.GetDataLength() + Attribute.HEADER_LENGTH;
                }
                else
                {
                    offset += Attribute.HEADER_LENGTH;
                }
            }

            return message;
        }