示例#1
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);
        }
示例#2
0
        /**
         * Called to notify this provider for an incoming message.
         * @param event the event object that contains the new message.
         */
        public virtual void HandleMessageEvent(StunMessageEvent @event)
        {
            Message msg = @event.GetMessage();

            //request
            if (msg is Request)
            {
                TransactionID serverTid = TransactionID.
                                          CreateTransactionID(msg.GetTransactionID());

                serverTransactions.Add(serverTid);
                if (requestListener != null)
                {
                    requestListener.requestReceived(@event);
                }
            }
            //response
            else if (msg is Response)
            {
                TransactionID tid = TransactionID.
                                    CreateTransactionID(msg.GetTransactionID());

                StunClientTransaction tran = (StunClientTransaction)clientTransactions[tid];
                clientTransactions.Remove(tid);

                if (tran != null)
                {
                    tran.HandleResponse(@event);
                }
                else
                {
                    //do nothing - just drop the phantom response.
                }
            }
        }
示例#3
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);
        }
        /**
         * Sends a binding request to the specified server address with only change
         * port flag set to true and change IP flag - to false.
         * @param serverAddress the address where to send the bindingRequest.
         * @return The returned message encapsulating event or null if no message
         * was received.
         * @throws StunException if an exception occurs while sending the messge
         */
        private StunMessageEvent doTestIII(StunAddress serverAddress)
        {
            Request request = MessageFactory.CreateBindingRequest();

            ChangeRequestAttribute changeRequest = (ChangeRequestAttribute)request.GetAttribute(Attribute.CHANGE_REQUEST);

            changeRequest.SetChangeIpFlag(false);
            changeRequest.SetChangePortFlag(true);

            StunMessageEvent evt =
                requestSender.SendRequestAndWaitForResponse(request, serverAddress);

#if false
            if (evt != null)
            {
                System.oout.println("Test III res=" + evt.getRemoteAddress().toString()
                                    + " - " + evt.getRemoteAddress().getHostName());
            }
            else
            {
                Console.WriteLine("NO RESPONSE received to Test III.");
            }
#endif

            return(evt);
        }
示例#5
0
        /**
         * Called to notify this provider for an incoming message.
         * @param event the event object that contains the new message.
         */
        public virtual void HandleMessageEvent(StunMessageEvent @event)
        {
            Message msg = @event.GetMessage();
            //request
            if(msg is Request)
            {
                TransactionID serverTid = TransactionID.
                    CreateTransactionID(msg.GetTransactionID());

                serverTransactions.Add(serverTid);
                if(requestListener != null)
                    requestListener.requestReceived(@event);
            }
                //response
            else if(msg is Response)
            {
                TransactionID tid = TransactionID.
                    CreateTransactionID(msg.GetTransactionID());

                StunClientTransaction tran = (StunClientTransaction)clientTransactions[tid];
                clientTransactions.Remove(tid);

                if(tran != null)
                {
                    tran.HandleResponse(@event);
                }
                else
                {
                    //do nothing - just drop the phantom response.
                }

            }
        }
示例#6
0
        /**
         * Does the message parsing.
         */
        public virtual void Run()
        {
            //add an extra try/catch block that handles uncatched errors and helps avoid
            //having dead threads in our pools.
            try
            {
                while (isRunning)
                {
                    RawMessage rawMessage = null;
                    rawMessage = messageQueue.Remove();

                    // were we asked to stop?
                    if (!IsRunning())
                    {
                        return;
                    }

                    //anything to parse?
                    if (rawMessage == null)
                    {
                        continue;
                    }

                    Message stunMessage = null;
                    try
                    {
                        stunMessage =
                            Message.Decode(rawMessage.GetBytes(),
                                           0,
                                           rawMessage.GetMessageLength());
                    }
                    catch (StunException ex)
                    {
                        errorHandler.HandleError("Failed to decode a stun mesage!",
                                                 ex);
                        continue;                         //let this one go and for better luck next time.
                    }

                    StunAddress sa = new StunAddress(
                        rawMessage.GetRemoteAddress().GetAddress(),
                        rawMessage.GetRemoteAddress().GetPort());

                    sa.Local = rawMessage.GetLocalAddress();

                    StunMessageEvent stunMessageEvent =
                        new StunMessageEvent(rawMessage.GetNetAccessPoint(),
                                             stunMessage,
                                             sa);
                    messageHandler.HandleMessageEvent(stunMessageEvent);
                }
            }
            catch (Exception err)
            {
                //notify and bail
                errorHandler.HandleFatalError(this, "Unexpected Error!", err);
            }
        }
示例#7
0
 /**
  * Saves the message event and notifies the discoverer thread so that
  * it may resume.
  * @param evt the newly arrived message event.
  */
 public virtual void ProcessResponse(StunMessageEvent evt)
 {
     Monitor.Enter(this);
     try
     {
         this.responseEvent = evt;
         Monitor.PulseAll(this);
     }
     finally
     {
         Monitor.Exit(this);
     }
 }
 /**
  * Saves the message event and notifies the discoverer thread so that
  * it may resume.
  * @param evt the newly arrived message event.
  */
 public virtual void ProcessResponse(StunMessageEvent evt)
 {
     Monitor.Enter(this);
     try
     {
         this.responseEvent = evt;
         Monitor.PulseAll(this);
     }
     finally
     {
         Monitor.Exit(this);
     }
 }
示例#9
0
        /**
         * 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);
            }
        }
示例#10
0
        /**
         * Does the message parsing.
         */
        public virtual void Run()
        {
            //add an extra try/catch block that handles uncatched errors and helps avoid
            //having dead threads in our pools.
            try
            {
                while (isRunning)
                {
                    RawMessage rawMessage = null;
                    rawMessage = messageQueue.Remove();

                    // were we asked to stop?
                    if (!IsRunning())
                        return;

                    //anything to parse?
                    if (rawMessage == null)
                        continue;

                    Message stunMessage = null;
                    try
                    {
                        stunMessage =
                            Message.Decode(rawMessage.GetBytes(),
                            0,
                            rawMessage.GetMessageLength());
                    }
                    catch (StunException ex)
                    {
                        errorHandler.HandleError("Failed to decode a stun mesage!",
                            ex);
                        continue; //let this one go and for better luck next time.
                    }

                    StunAddress sa = new StunAddress(
                        rawMessage.GetRemoteAddress().GetAddress(),
                        rawMessage.GetRemoteAddress().GetPort() );

                    sa.Local = rawMessage.GetLocalAddress();

                    StunMessageEvent stunMessageEvent =
                        new StunMessageEvent(rawMessage.GetNetAccessPoint(),
                        stunMessage,
                        sa);
                    messageHandler.HandleMessageEvent(stunMessageEvent);
                }
            }
            catch(Exception err)
            {
                //notify and bail
                errorHandler.HandleFatalError(this, "Unexpected Error!", err);
            }
        }
 /**
  * Dispatches the response then cancels itself and notifies the StunProvider
  * for its termination.
  * @param evt the event that contains the newly received message
  */
 public virtual void HandleResponse(StunMessageEvent evt)
 {
     this.Cancel();
     this.responseCollector.ProcessResponse(evt);
 }
        /**
         * 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);
            }
        }
 /**
  * Dispatches the response then cancels itself and notifies the StunProvider
  * for its termination.
  * @param evt the event that contains the newly received message
  */
 public virtual void HandleResponse(StunMessageEvent evt)
 {
     this.Cancel();
     this.responseCollector.ProcessResponse(evt);
 }
        /**
         * Implements the discovery process itself (see class description).
         * @return a StunDiscoveryReport containing details about the network
         * configuration of the host where the class is executed.
         * @throws StunException ILLEGAL_STATE if the discoverer has not been started
         * NETWORK_ERROR or ILLEGAL_ARGUMENT if a failure occurs while executing
         * the discovery algorithm
         */
        virtual public StunDiscoveryReport determineAddress()
        {
            checkStarted();
            StunDiscoveryReport report = new StunDiscoveryReport();
            StunMessageEvent    evt    = doTestI(serverAddress);

            if (evt == null)
            {
                //UDP Blocked
                report.SetNatType(StunDiscoveryReport.UDP_BLOCKING_FIREWALL);
                return(report);
            }
            else
            {
                StunAddress mappedAddress = ((MappedAddressAttribute)evt.GetMessage().
                                             GetAttribute(Attribute.MAPPED_ADDRESS)).GetAddress();

                StunAddress backupServerAddress = ((ChangedAddressAttribute)evt.GetMessage().
                                                   GetAttribute(Attribute.CHANGED_ADDRESS)).GetAddress();
                report.SetPublicAddress(mappedAddress);
                if (mappedAddress.Equals(apDescriptor.GetAddress()))
                {
                    evt = doTestII(serverAddress);
                    if (evt == null)
                    {
                        //Sym UDP Firewall
                        report.SetNatType(StunDiscoveryReport.SYMMETRIC_UDP_FIREWALL);
                        return(report);
                    }
                    else
                    {
                        //open internet
                        report.SetNatType(StunDiscoveryReport.OPEN_INTERNET);
                        return(report);
                    }
                }
                else
                {
                    evt = doTestII(serverAddress);
                    if (evt == null)
                    {
                        evt = doTestI(backupServerAddress);
                        if (evt == null)
                        {
                            // System.oout.println("Failed to receive a response from backup stun server!");
                            return(report);
                        }
                        StunAddress mappedAddress2 = ((MappedAddressAttribute)evt.GetMessage().
                                                      GetAttribute(Attribute.MAPPED_ADDRESS)).GetAddress();
                        if (mappedAddress.Equals(mappedAddress2))
                        {
                            evt = doTestIII(serverAddress);
                            if (evt == null)
                            {
                                //port restricted cone
                                report.SetNatType(StunDiscoveryReport.PORT_RESTRICTED_CONE_NAT);
                                return(report);
                            }
                            else
                            {
                                //restricted cone
                                report.SetNatType(StunDiscoveryReport.RESTRICTED_CONE_NAT);
                                return(report);
                            }
                        }
                        else
                        {
                            //Symmetric NAT
                            report.SetNatType(StunDiscoveryReport.SYMMETRIC_NAT);
                            return(report);
                        }
                    }
                    else
                    {
                        //full cone
                        report.SetNatType(StunDiscoveryReport.FULL_CONE_NAT);
                        return(report);
                    }
                }
            }
        }