Beispiel #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);
        }
        /**
         * Constructs a StunMessageEvent according to the specified message.
         * @param source the access point that received the message
         * @param message the message itself
         * @param remoteAddress the address that sent the message
         */
        public StunMessageEvent(NetAccessPointDescriptor source,
			Message                  message,
			StunAddress        remoteAddress)
        {
            this.message = message;
            this.remoteAddress  = remoteAddress;
        }
        //--------------- SENDING MESSAGES -----------------------------------------

        /**
         * Sends the specified stun message through the specified access point.
         * @param stunMessage the message to send
         * @param apDescriptor the access point to use to send the message
         * @param address the destination of the message.
         * @throws StunException if message encoding fails, ILLEGAL_ARGUMENT if the
         * apDescriptor references an access point that had not been installed,
         * NETWORK_ERROR if an error occurs while sending message bytes through the
         * network socket.
         */
        public virtual void SendMessage(Message stunMessage,
                                        NetAccessPointDescriptor apDescriptor,
                                        StunAddress address)
        {
            byte[]         bytes = stunMessage.Encode();
            NetAccessPoint ap    = (NetAccessPoint)netAccessPoints[apDescriptor];

            if (ap == null)
            {
                throw new StunException(
                          StunException.ILLEGAL_ARGUMENT,
                          "The specified access point had not been installed.");
            }

            try
            {
                ap.SendMessage(bytes, address);
            }
            catch (Exception ex)
            {
                throw new StunException(StunException.NETWORK_ERROR,
                                        "An Exception occurred while sending message bytes "
                                        + "through a network socket!",
                                        ex);
            }
        }
 /**
  * Constructs a StunMessageEvent according to the specified message.
  * @param source the access point that received the message
  * @param message the message itself
  * @param remoteAddress the address that sent the message
  */
 public StunMessageEvent(NetAccessPointDescriptor source,
                         Message message,
                         StunAddress remoteAddress)
 {
     this.message       = message;
     this.remoteAddress = remoteAddress;
 }
Beispiel #5
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);
        }
Beispiel #6
0
 /**
  * Creates a network access point.
  * @param apDescriptor the address and port where to bind.
  * @param messageQueue the FIFO list where incoming messages should be queued
  * @param errorHandler the instance to notify when errors occur.
  */
 public NetAccessPoint(NetAccessPointDescriptor apDescriptor,
                       MessageQueue messageQueue,
                       ErrorHandler errorHandler)
 {
     this.apDescriptor = apDescriptor;
     this.messageQueue = messageQueue;
     this.errorHandler = errorHandler;
 }
Beispiel #7
0
        /**
         * Creates a network access point.
         * @param apDescriptor the address and port where to bind.
         * @param messageQueue the FIFO list where incoming messages should be queued
         * @param errorHandler the instance to notify when errors occur.
         */
        public NetAccessPoint(NetAccessPointDescriptor apDescriptor,
			MessageQueue             messageQueue,
			ErrorHandler			    errorHandler)
        {
            this.apDescriptor = apDescriptor;
            this.messageQueue = messageQueue;
            this.errorHandler = errorHandler;
        }
        /**
         * Shuts down the underlying stack and prepares the object for garbage
         * collection.
         */
        public virtual void ShutDown()
        {
            StunStack.ShutDown();
            stunStack     = null;
            stunProvider  = null;
            apDescriptor  = null;
            requestSender = null;

            this.started = false;
        }
        /**
         * Stops and deletes the specified access point.
         * @param apDescriptor the access  point to remove
         */
        public virtual void RemoveNetAccessPoint(NetAccessPointDescriptor apDescriptor)
        {
            NetAccessPoint ap = (NetAccessPoint)netAccessPoints[apDescriptor];

            netAccessPoints.Remove(apDescriptor);

            if (ap != null)
            {
                ap.Stop();
            }
        }
Beispiel #10
0
        /**
         * Creates and starts a new access point according to the given descriptor.
         * If the specified access point has already been installed the method
         * has no effect.
         *
         * @param apDescriptor   a description of the access point to create.
         * @throws StunException if we fail to create or start the accesspoint.
         */
        public virtual void InstallNetAccessPoint(NetAccessPointDescriptor apDescriptor)
        {
            if (netAccessPoints.ContainsKey(apDescriptor))
            {
                return;
            }

            NetAccessPoint ap = new NetAccessPoint(apDescriptor, messageQueue, this);

            netAccessPoints[apDescriptor] = ap;

            ap.Start();
        }
        /**
         * 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));
        }
Beispiel #12
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();
        }
Beispiel #13
0
        /**
         * Sends the specified response message through the specified access point.
         *
         * @param transactionID the id of the transaction to use when sending the
         *    response. Actually we are getting kind of redundant here as we already
         *    have the id in the response object, but I am bringing out as an extra
         *    parameter as the user might otherwise forget to explicitly set it.
         * @param response      the message to send.
         * @param sendThrough   the access point to use when sending the message.
         * @param sendTo        the destination of the message.
         * @throws StunException TRANSACTION_DOES_NOT_EXIST if the response message
         * has an invalid transaction id. <br/>
         * 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 SendResponse(byte[]                   transactionID,
                                         Response response,
                                         NetAccessPointDescriptor sendThrough,
                                         StunAddress sendTo)
        {
            stunStack.CheckStarted();

            TransactionID tid = TransactionID.CreateTransactionID(transactionID);


            serverTransactions.Remove(tid);
#if false
            throw new StunException(StunException.TRANSACTION_DOES_NOT_EXIST,
                                    "The trensaction specified in the response "
                                    + "object does not exist.");
#endif

            response.SetTransactionID(transactionID);
            GetNetAccessManager().SendMessage(response, sendThrough, sendTo);
        }
Beispiel #14
0
        /**
         * Creates and starts a new access point based on the specified socket.
         * If the specified access point has already been installed the method
         * has no effect.
         *
         * @param  socket   the socket that the access point should use.
         * @return an access point descriptor to allow further management of the
         * newly created access point.
         * @throws StunException if we fail to create or start the accesspoint.
         */

        public NetAccessPointDescriptor InstallNetAccessPoint(MyUdpClient socket)
        {
            //no null check - let it through a null pointer exception
            StunAddress address = new StunAddress(socket.GetAddress().ToString(), socket.GetPort());
            NetAccessPointDescriptor apDescriptor = new NetAccessPointDescriptor(address);

            if (netAccessPoints.ContainsKey(apDescriptor))
            {
                return(apDescriptor);
            }

            NetAccessPoint ap = new NetAccessPoint(apDescriptor, messageQueue, this);

            //call the useExternalSocket method to avoid closing the socket when
            //removing the accesspoint. Bug Report - Dave Stuart - SipQuest
            ap.UseExternalSocket(socket);
            netAccessPoints[apDescriptor] = (ap);

            ap.Start();

            return(apDescriptor);
        }
Beispiel #15
0
        /**
         * Constructs a raw message with the specified field values. All parameters
         * are cloned before being assigned to class members.
         *
         * @param messageBytes      the message itself.
         * @param remoteAddress     the address where the message came from.
         * @param remotePort        the port where the message came from.
         * @param netApDescriptor   the access point the received the message.s
         *
         * @throws NullPointerException if one or more of the parameters were null.
         */
        public RawMessage(byte[]                   messageBytes,
                          int messageLength,
                          IPAddress remoteAddress,
                          int remotePort,
                          IPAddress localAddress,
                          int localPort,
                          NetAccessPointDescriptor netApDescriptor)
        {
            //... don't do a null check - let it throw an NP exception
            string s = localAddress.ToString();

            this.messageBytes  = new byte[messageBytes.Length];
            this.messageLength = messageLength;
            for (int x = 0; x < messageBytes.Length; x++)
            {
                this.messageBytes[x] = messageBytes[x];
            }

            this.remoteAddress        = new InetSocketAddress(remoteAddress, remotePort);
            this.receivingAccessPoint =
                (NetAccessPointDescriptor)netApDescriptor.Clone();
        }
Beispiel #16
0
        /**
         * Constructs a raw message with the specified field values. All parameters
         * are cloned before being assigned to class members.
         *
         * @param messageBytes      the message itself.
         * @param remoteAddress     the address where the message came from.
         * @param remotePort        the port where the message came from.
         * @param netApDescriptor   the access point the received the message.s
         *
         * @throws NullPointerException if one or more of the parameters were null.
         */
        public RawMessage(byte[]                   messageBytes,
			int                      messageLength,
			IPAddress				remoteAddress,
			int						remotePort,
			IPAddress localAddress,
			int localPort,
			NetAccessPointDescriptor netApDescriptor)
        {
            //... don't do a null check - let it throw an NP exception
            string s = localAddress.ToString();

            this.messageBytes  = new byte[messageBytes.Length];
            this.messageLength = messageLength;
            for (int x = 0; x < messageBytes.Length; x++)
            {
                this.messageBytes[x] = messageBytes[x];
            }

            this.remoteAddress = new InetSocketAddress(remoteAddress, remotePort);
            this.receivingAccessPoint    =
                (NetAccessPointDescriptor)netApDescriptor.Clone();
        }
Beispiel #17
0
        /**
         * Creates and starts a new access point based on the specified socket.
         * If the specified access point has already been installed the method
         * has no effect.
         *
         * @param  socket   the socket that the access point should use.
         * @return an access point descriptor to allow further management of the
         * newly created access point.
         * @throws StunException if we fail to create or start the accesspoint.
         */
        public NetAccessPointDescriptor InstallNetAccessPoint(MyUdpClient socket)
        {
            //no null check - let it through a null pointer exception
            StunAddress address = new StunAddress(socket.GetAddress().ToString(), socket.GetPort());
            NetAccessPointDescriptor apDescriptor = new NetAccessPointDescriptor(address);

            if(netAccessPoints.ContainsKey(apDescriptor))
                return apDescriptor;

            NetAccessPoint ap = new NetAccessPoint(apDescriptor, messageQueue, this);
            //call the useExternalSocket method to avoid closing the socket when
            //removing the accesspoint. Bug Report - Dave Stuart - SipQuest
            ap.UseExternalSocket(socket);
            netAccessPoints[apDescriptor] = (ap);

            ap.Start();

            return apDescriptor;
        }
Beispiel #18
0
        /**
         * Creates and starts a new access point according to the given descriptor.
         * If the specified access point has already been installed the method
         * has no effect.
         *
         * @param apDescriptor   a description of the access point to create.
         * @throws StunException if we fail to create or start the accesspoint.
         */
        public virtual void InstallNetAccessPoint(NetAccessPointDescriptor apDescriptor)
        {
            if(netAccessPoints.ContainsKey(apDescriptor))
                return;

            NetAccessPoint ap = new NetAccessPoint(apDescriptor, messageQueue, this);
            netAccessPoints[apDescriptor] = ap;

            ap.Start();
        }
Beispiel #19
0
        /**
         * Sends the specified response message through the specified access point.
         *
         * @param transactionID the id of the transaction to use when sending the
         *    response. Actually we are getting kind of redundant here as we already
         *    have the id in the response object, but I am bringing out as an extra
         *    parameter as the user might otherwise forget to explicitly set it.
         * @param response      the message to send.
         * @param sendThrough   the access point to use when sending the message.
         * @param sendTo        the destination of the message.
         * @throws StunException TRANSACTION_DOES_NOT_EXIST if the response message
         * has an invalid transaction id. <br/>
         * 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 SendResponse(byte[]                   transactionID,
			Response                 response,
			NetAccessPointDescriptor sendThrough,
			StunAddress                  sendTo)
        {
            stunStack.CheckStarted();

            TransactionID tid = TransactionID.CreateTransactionID(transactionID);

            serverTransactions.Remove(tid);
            #if false
                throw new StunException(StunException.TRANSACTION_DOES_NOT_EXIST,
                    "The trensaction specified in the response "
                    +"object does not exist.");
            #endif

            response.SetTransactionID(transactionID);
            GetNetAccessManager().SendMessage(response, sendThrough, sendTo);
        }
        /**
         * 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));
        }
Beispiel #21
0
        /**
         * Stops and deletes the specified access point.
         * @param apDescriptor the access  point to remove
         */
        public virtual void RemoveNetAccessPoint(NetAccessPointDescriptor apDescriptor)
        {
            CheckStarted();

            netAccessManager.RemoveNetAccessPoint(apDescriptor);
        }
Beispiel #22
0
 public BlockingRequestSender(StunProvider stunProvider,
                              NetAccessPointDescriptor apDescriptor)
 {
     this.stunProvider = stunProvider;
     this.apDescriptor = apDescriptor;
 }
Beispiel #23
0
        /**
         * Creates and starts the specified Network Access Point.
         *
         * @param apDescriptor A descriptor containing the address and port of the
         * STUN server that the newly created access point will communicate with.
         * @throws StunException
         *           <p>NETWORK_ERROR if we fail to create or bind the datagram socket.</p>
         *           <p>ILLEGAL_STATE if the stack had not been started.</p>
         */
        public virtual void InstallNetAccessPoint(NetAccessPointDescriptor apDescriptor)
        {
            CheckStarted();

            netAccessManager.InstallNetAccessPoint(apDescriptor);
        }
        /**
         * Clones the NetAccessPointDescriptor.
         *
         * @return a copy of this NetAccessPointDescriptor.
         */
        public virtual object Clone()
        {
            NetAccessPointDescriptor napd = new NetAccessPointDescriptor(stunAddr);

            return napd;
        }
        public BlockingRequestSender(StunProvider             stunProvider,
			NetAccessPointDescriptor apDescriptor)
        {
            this.stunProvider = stunProvider;
            this.apDescriptor = apDescriptor;
        }
        /**
         * Creates a StunAddressDiscoverer. In order to use it one must start the
         * discoverer.
         * @param apDescriptor the address where the stach should bind.
         * @param serverAddress the address of the server to interrogate.
         */
        public NetworkConfigurationDiscoveryProcess(NetAccessPointDescriptor apDescriptor,
			StunAddress serverAddress)
        {
            this.apDescriptor  = apDescriptor;
            this.serverAddress = serverAddress;
        }
        /**
         * Shuts down the underlying stack and prepares the object for garbage
         * collection.
         */
        public virtual void ShutDown()
        {
            StunStack.ShutDown();
            stunStack     = null;
            stunProvider  = null;
            apDescriptor  = null;
            requestSender = null;

            this.started = false;
        }
Beispiel #28
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();
        }
Beispiel #29
0
        /**
         * Creates and starts the specified Network Access Point.
         *
         * @param apDescriptor A descriptor containing the address and port of the
         * STUN server that the newly created access point will communicate with.
         * @throws StunException
         *           <p>NETWORK_ERROR if we fail to create or bind the datagram socket.</p>
         *           <p>ILLEGAL_STATE if the stack had not been started.</p>
         */
        public virtual void InstallNetAccessPoint(NetAccessPointDescriptor apDescriptor)
        {
            CheckStarted();

            netAccessManager.InstallNetAccessPoint(apDescriptor);
        }
Beispiel #30
0
        /**
         * Stops and deletes the specified access point.
         * @param apDescriptor the access  point to remove
         */
        public virtual void RemoveNetAccessPoint(NetAccessPointDescriptor apDescriptor)
        {
            NetAccessPoint ap = (NetAccessPoint)netAccessPoints[apDescriptor];

            netAccessPoints.Remove(apDescriptor);

            if(ap != null)
                ap.Stop();
        }
Beispiel #31
0
        //--------------- SENDING MESSAGES -----------------------------------------
        /**
         * Sends the specified stun message through the specified access point.
         * @param stunMessage the message to send
         * @param apDescriptor the access point to use to send the message
         * @param address the destination of the message.
         * @throws StunException if message encoding fails, ILLEGAL_ARGUMENT if the
         * apDescriptor references an access point that had not been installed,
         * NETWORK_ERROR if an error occurs while sending message bytes through the
         * network socket.
         */
        public virtual void SendMessage(Message                  stunMessage,
			NetAccessPointDescriptor apDescriptor,
			StunAddress                  address)
        {
            byte[] bytes = stunMessage.Encode();
            NetAccessPoint ap = (NetAccessPoint)netAccessPoints[apDescriptor];

            if(ap == null)
                throw new StunException(
                    StunException.ILLEGAL_ARGUMENT,
                    "The specified access point had not been installed.");

            try
            {
                ap.SendMessage(bytes, address);
            }
            catch (Exception ex)
            {
                throw new StunException(StunException.NETWORK_ERROR,
                    "An Exception occurred while sending message bytes "
                    +"through a network socket!",
                    ex);
            }
        }
        /**
         * Creates a StunAddressDiscoverer. In order to use it one must start the
         * discoverer.
         * @param localAddress the address where the stach should bind.
         * @param serverAddress the address of the server to interrogate.
         */
        public NetworkConfigurationDiscoveryProcess(StunAddress localAddress,
			StunAddress serverAddress)
        {
            apDescriptor       = new NetAccessPointDescriptor(localAddress);
            this.serverAddress = serverAddress;
        }
Beispiel #33
0
        /**
         * Stops and deletes the specified access point.
         * @param apDescriptor the access  point to remove
         */
        public virtual void RemoveNetAccessPoint(NetAccessPointDescriptor apDescriptor)
        {
            CheckStarted();

            netAccessManager.RemoveNetAccessPoint(apDescriptor);
        }
 /**
  * Creates a StunAddressDiscoverer. In order to use it one must start the
  * discoverer.
  * @param apDescriptor the address where the stach should bind.
  * @param serverAddress the address of the server to interrogate.
  */
 public NetworkConfigurationDiscoveryProcess(NetAccessPointDescriptor apDescriptor,
                                             StunAddress serverAddress)
 {
     this.apDescriptor  = apDescriptor;
     this.serverAddress = serverAddress;
 }
 /**
  * Creates a StunAddressDiscoverer. In order to use it one must start the
  * discoverer.
  * @param localAddress the address where the stach should bind.
  * @param serverAddress the address of the server to interrogate.
  */
 public NetworkConfigurationDiscoveryProcess(StunAddress localAddress,
                                             StunAddress serverAddress)
 {
     apDescriptor       = new NetAccessPointDescriptor(localAddress);
     this.serverAddress = serverAddress;
 }
        /**
         * Clones the NetAccessPointDescriptor.
         *
         * @return a copy of this NetAccessPointDescriptor.
         */
        virtual public object Clone()
        {
            NetAccessPointDescriptor napd = new NetAccessPointDescriptor(stunAddr);

            return(napd);
        }