示例#1
0
        /// <summary>
        /// TODO: Documentation StunClient_OnReceivedIndication
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="receivedMsg"></param>
        private void StunClient_OnReceivedIndication(object sender, StunMessage receivedMsg)
        {
            switch (receivedMsg.MethodType)
            {
                case StunMethodType.ConnectionAttempt:
                    if (this.OnConnectionAttemptReceived != null)
                        this.OnConnectionAttemptReceived(this, receivedMsg);
                    break;

                case StunMethodType.Data:
                    if (this.OnDataReceived != null)
                        this.OnDataReceived(this, receivedMsg);
                    break;
            }
        }
示例#2
0
        /// <summary>
        /// TODO: Documentation StunClient_OnReceivedError
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="receivedMsg"></param>
        /// <param name="sentMsg"></param>
        /// <param name="transactionObject"></param>
        private void StunClient_OnReceivedError(object sender, StunMessage receivedMsg, StunMessage sentMsg, object transactionObject)
        {
            switch (receivedMsg.MethodType)
            {
                case StunMethodType.Allocate:
                    if (receivedMsg.Stun.ErrorCode.ErrorType == ErrorCodeType.Unauthorized)
                    {
                        String[] credentials = transactionObject as String[];

                        if (credentials != null)
                            this.AllocateRetry(receivedMsg, credentials[0], credentials[1]);
                        else
                            if (this.OnAllocateFailed != null)
                                this.OnAllocateFailed(this, receivedMsg, sentMsg, transactionObject);
                    }
                    break;
            }
        }
示例#3
0
        /// <summary>
        /// TODO: Documentation turnManager_OnConnectionBindSucceed
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="connectedSocket"></param>
        /// <param name="receivedMsg"></param>
        private void turnManager_OnConnectionBindSucceed(object sender, Socket connectedSocket, StunMessage receivedMsg)
        {
            if (this.OnTurnConnectionBindSucceed != null)
                this.OnTurnConnectionBindSucceed(this, connectedSocket, this.StartingSessionSid, this.StartingSessionRecipient);

            if (this.OnConnectionTryEnded != null)
                this.OnConnectionTryEnded(this, this.StartingSessionSid);

            this.CancelStartingSession();
        }
示例#4
0
        /// <summary>
        /// TODO: Documentation StunClient_OnReceivedSuccessResponse
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="receivedMsg"></param>
        /// <param name="sentMsg"></param>
        /// <param name="transactionObject"></param>
        private void StunClient_OnReceivedSuccessResponse(object sender, StunMessage receivedMsg, StunMessage sentMsg, object transactionObject)
        {
            switch (receivedMsg.MethodType)
            {
                case StunMethodType.Allocate:
                    TurnAllocation allocation = new TurnAllocation()
                    {
                        Username = sentMsg.Stun.Username.ValueString,
                        Password = transactionObject as String,
                        Realm = sentMsg.Stun.Realm.ValueString,
                        Nonce = sentMsg.Stun.Nonce.ValueString,
                        RelayedMappedAddress = receivedMsg.Turn.XorRelayedAddress,
                        MappedAddress = receivedMsg.Stun.XorMappedAddress,
                        StartTime = DateTime.Now,
                        LifeTime = StunUtilities.ReverseBytes(BitConverter.ToUInt32(receivedMsg.Turn.LifeTime.Value, 0))
                    };

                    if (this.Allocations.ContainsKey(receivedMsg.Turn.XorRelayedAddress))
                        this.Allocations[receivedMsg.Turn.XorRelayedAddress] = allocation;
                    else
                    {
                        this.Allocations.Add(receivedMsg.Turn.XorRelayedAddress, allocation);

                        if (this.OnAllocateSucceed != null)
                            this.OnAllocateSucceed(this, allocation, sentMsg, receivedMsg);
                    }
                    break;

                case StunMethodType.CreatePermission:
                    TurnPermission permission = new TurnPermission()
                    {
                        PeerAddress = sentMsg.Turn.XorPeerAddress,
                        StartTime = DateTime.Now,
                        LifeTime = 300
                    };
                    TurnAllocation permAllocation = transactionObject as TurnAllocation;

                    if (permAllocation.Permissions.ContainsKey(sentMsg.Turn.XorPeerAddress))
                        permAllocation.Permissions[sentMsg.Turn.XorPeerAddress] = permission;
                    else
                    {
                        permAllocation.Permissions.Add(sentMsg.Turn.XorPeerAddress, permission);

                        if (this.OnCreatePermissionSucceed != null)
                            this.OnCreatePermissionSucceed(this, permAllocation, permission, sentMsg, receivedMsg);
                    }

                    break;

                case StunMethodType.ChannelBind:
                    TurnChannel channel = new TurnChannel()
                    {
                        Channel = sentMsg.Turn.ChannelNumber,
                        PeerAddress = sentMsg.Turn.XorPeerAddress,
                        StartTime = DateTime.Now,
                        LifeTime = 600
                    };
                    TurnAllocation channelAllocation = transactionObject as TurnAllocation;

                    if (channelAllocation.Channels.ContainsKey(sentMsg.Turn.ChannelNumber))
                        channelAllocation.Channels[sentMsg.Turn.ChannelNumber] = channel;
                    else
                    {
                        channelAllocation.Channels.Add(sentMsg.Turn.ChannelNumber, channel);

                        if (this.OnChannelBindSucceed != null)
                            this.OnChannelBindSucceed(this, transactionObject as TurnAllocation, channel, sentMsg, receivedMsg);
                    }
                    break;

                case StunMethodType.ConnectionBind:
                    if (this.OnConnectionBindSucceed != null)
                        this.OnConnectionBindSucceed(this, transactionObject as Socket, receivedMsg);
                    break;
            }
        }
示例#5
0
        /// <summary>
        /// TODO: Documentation SendIndication
        /// </summary>
        /// <param name="xorPeerAddress"></param>
        /// <param name="data"></param>
        /// <param name="allocation"></param>
        public void SendIndication(XorMappedAddress xorPeerAddress, byte[] data, TurnAllocation allocation)
        {
            StunMessage msg = new StunMessage(StunMethodType.Send, StunMethodClass.Indication, StunUtilities.NewTransactionId);

            msg.Turn.XorPeerAddress = xorPeerAddress;
            msg.Turn.Data = new StunAttribute(StunAttributeType.Data, data);
            msg.Stun.Username = new UTF8Attribute(StunAttributeType.Username, allocation.Username);
            msg.Stun.Realm = new UTF8Attribute(StunAttributeType.Realm, allocation.Realm);
            msg.Stun.Nonce = new UTF8Attribute(StunAttributeType.Nonce, allocation.Nonce);

            msg.AddMessageIntegrity(allocation.Password, true);

            this.StunClient.BeginSendMessage(msg, null);
        }
示例#6
0
        /// <summary>
        /// Sample usage of this StunClient
        /// </summary>
        /// <param name="args">Unused</param>
        private static void Main(string[] args)
        {
            KeyValuePair<IPEndPoint, IPEndPoint> stunKeyValue = StunUtilities.GetMappedAddressFrom(null,
                                                                                                   new IPEndPoint(IPAddress.Parse("66.228.45.110"), StunClient.DEFAULT_STUN_PORT),
                                                                                                   ProtocolType.Udp);

            StunMessage msg = new StunMessage(StunMethodType.Binding, StunMethodClass.Request, StunUtilities.NewTransactionId);
            msg.Stun.Realm = new UTF8Attribute(StunAttributeType.Realm, "Hello World !");
            msg.Stun.Username = new UTF8Attribute(StunAttributeType.Username, "Bob");

            byte[] octets = msg;
            StunMessage msgCopy = octets;

            // Reuse of an existing local IPEndPoint makes the three requests returning 
            // the same MappedAddress IPEndPoint if this client is behind a Cone NAT
            StunClient cli1 = new StunClient(stunKeyValue.Key,
                                             new IPEndPoint(IPAddress.Parse("66.228.45.110"), StunClient.DEFAULT_STUNS_PORT),
                                             ProtocolType.Tcp, null,
                                             (sender, certificate, chain, sslPolicyErrors) => true);

            // Sample TLS over TCP working with ejabberd but may not work with the sample server IP given here
            cli1.Connect();
            StunMessage resp1 = cli1.SendMessage(msgCopy);
            cli1.Disconnect();

            msgCopy.ClearAttributes();

            StunClient cli2 = new StunClient(stunKeyValue.Key,
                                             new IPEndPoint(IPAddress.Parse("132.177.123.13"), StunClient.DEFAULT_STUN_PORT),
                                             ProtocolType.Udp, null, null);

            cli2.Connect();
            StunMessage resp2 = cli2.SendMessage(msgCopy);
            cli2.Disconnect();
        }
示例#7
0
        /// <summary>
        /// Computes a HMAC SHA1 based on this StunMessage attributes
        /// </summary>
        /// <param name="hmacSha1Key">The key of HMAC SHA1 computation algorithm</param>
        /// <returns>The HMAC computed value of this StunMessage</returns>
        private byte[] ComputeHMAC(byte[] hmacSha1Key)
        {
            byte[] hashed;

            using (HMACSHA1 hmacSha1 = new HMACSHA1(hmacSha1Key))
            {
                StunMessage thisCopy = new StunMessage(this.MethodType, this.MethodClass, this.TransactionID);

                foreach (var item in this.attributesList)
                {
                    if (item.Key == StunAttributeType.MessageIntegrity)
                        break;

                    thisCopy.SetAttribute(item.Value);
                }

                if (this.Stun.FingerPrint != null)
                    thisCopy.SetAttribute(this.Stun.FingerPrint);

                byte[] thisCopyBytes = thisCopy;

                // Insert a fake message length for HMAC computation as described in [RFC5489#15.4]
                UInt16 dummyLength = StunUtilities.ReverseBytes((UInt16)(thisCopy.MessageLength + 24)); // 20 hmac + 4 header

                BitConverter.GetBytes(dummyLength).CopyTo(thisCopyBytes, 2);

                hashed = hmacSha1.ComputeHash(thisCopyBytes);
            }

            return hashed;
        }
示例#8
0
        /// <summary>
        /// TODO: Documentation RefreshAllocation
        /// </summary>
        /// <param name="allocation"></param>
        /// <param name="lifeTime"></param>
        public void RefreshAllocation(TurnAllocation allocation, UInt32 lifeTime)
        {
            StunMessage msg = new StunMessage(StunMethodType.Refresh, StunMethodClass.Request, StunUtilities.NewTransactionId);

            msg.Stun.Username = new UTF8Attribute(StunAttributeType.Username, allocation.Username);
            msg.Stun.Realm = new UTF8Attribute(StunAttributeType.Realm, allocation.Realm);
            msg.Stun.Nonce = new UTF8Attribute(StunAttributeType.Nonce, allocation.Nonce);
            msg.Turn.LifeTime = new StunAttribute(StunAttributeType.LifeTime, BitConverter.GetBytes(StunUtilities.ReverseBytes(lifeTime)));

            msg.AddMessageIntegrity(allocation.Password, true);

            this.StunClient.BeginSendMessage(msg, null);
        }
示例#9
0
        /// <summary>
        /// TODO: Documentation StunClient_OnReceivedError
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="receivedMsg"></param>
        /// <param name="sentMsg"></param>
        /// <param name="transactionObject"></param>
        private void StunClient_OnReceivedError(object sender, StunMessage receivedMsg, StunMessage sentMsg, object transactionObject)
        {
            switch (receivedMsg.MethodType)
            {
            case StunMethodType.Allocate:
                if (receivedMsg.Stun.ErrorCode.ErrorType == ErrorCodeType.Unauthorized)
                {
                    String[] credentials = transactionObject as String[];

                    if (credentials != null)
                    {
                        this.AllocateRetry(receivedMsg, credentials[0], credentials[1]);
                    }
                    else
                    if (this.OnAllocateFailed != null)
                    {
                        this.OnAllocateFailed(this, receivedMsg, sentMsg, transactionObject);
                    }
                }
                break;
            }
        }
示例#10
0
        /// <summary>
        /// TODO: Documentation Allocate
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        public void Allocate(String username, String password)
        {
            StunMessage msg = new StunMessage(StunMethodType.Allocate, StunMethodClass.Request, StunUtilities.NewTransactionId);

            this.StunClient.BeginSendMessage(msg, new String[] { username, password });
        }
示例#11
0
        /// <summary>
        /// TODO: Documentation StunClient_OnReceivedSuccessResponse
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="receivedMsg"></param>
        /// <param name="sentMsg"></param>
        /// <param name="transactionObject"></param>
        private void StunClient_OnReceivedSuccessResponse(object sender, StunMessage receivedMsg, StunMessage sentMsg, object transactionObject)
        {
            switch (receivedMsg.MethodType)
            {
            case StunMethodType.Allocate:
                TurnAllocation allocation = new TurnAllocation()
                {
                    Username             = sentMsg.Stun.Username.ValueString,
                    Password             = transactionObject as String,
                    Realm                = sentMsg.Stun.Realm.ValueString,
                    Nonce                = sentMsg.Stun.Nonce.ValueString,
                    RelayedMappedAddress = receivedMsg.Turn.XorRelayedAddress,
                    MappedAddress        = receivedMsg.Stun.XorMappedAddress,
                    StartTime            = DateTime.Now,
                    LifeTime             = StunUtilities.ReverseBytes(BitConverter.ToUInt32(receivedMsg.Turn.LifeTime.Value, 0))
                };

                if (this.Allocations.ContainsKey(receivedMsg.Turn.XorRelayedAddress))
                {
                    this.Allocations[receivedMsg.Turn.XorRelayedAddress] = allocation;
                }
                else
                {
                    this.Allocations.Add(receivedMsg.Turn.XorRelayedAddress, allocation);

                    if (this.OnAllocateSucceed != null)
                    {
                        this.OnAllocateSucceed(this, allocation, sentMsg, receivedMsg);
                    }
                }
                break;

            case StunMethodType.CreatePermission:
                TurnPermission permission = new TurnPermission()
                {
                    PeerAddress = sentMsg.Turn.XorPeerAddress,
                    StartTime   = DateTime.Now,
                    LifeTime    = 300
                };
                TurnAllocation permAllocation = transactionObject as TurnAllocation;

                if (permAllocation.Permissions.ContainsKey(sentMsg.Turn.XorPeerAddress))
                {
                    permAllocation.Permissions[sentMsg.Turn.XorPeerAddress] = permission;
                }
                else
                {
                    permAllocation.Permissions.Add(sentMsg.Turn.XorPeerAddress, permission);

                    if (this.OnCreatePermissionSucceed != null)
                    {
                        this.OnCreatePermissionSucceed(this, permAllocation, permission, sentMsg, receivedMsg);
                    }
                }

                break;

            case StunMethodType.ChannelBind:
                TurnChannel channel = new TurnChannel()
                {
                    Channel     = sentMsg.Turn.ChannelNumber,
                    PeerAddress = sentMsg.Turn.XorPeerAddress,
                    StartTime   = DateTime.Now,
                    LifeTime    = 600
                };
                TurnAllocation channelAllocation = transactionObject as TurnAllocation;

                if (channelAllocation.Channels.ContainsKey(sentMsg.Turn.ChannelNumber))
                {
                    channelAllocation.Channels[sentMsg.Turn.ChannelNumber] = channel;
                }
                else
                {
                    channelAllocation.Channels.Add(sentMsg.Turn.ChannelNumber, channel);

                    if (this.OnChannelBindSucceed != null)
                    {
                        this.OnChannelBindSucceed(this, transactionObject as TurnAllocation, channel, sentMsg, receivedMsg);
                    }
                }
                break;

            case StunMethodType.ConnectionBind:
                if (this.OnConnectionBindSucceed != null)
                {
                    this.OnConnectionBindSucceed(this, transactionObject as Socket, receivedMsg);
                }
                break;
            }
        }
示例#12
0
        /// <summary>
        /// Sends a StunMessage to the connected STUN Server.
        /// </summary>
        /// <param name="msgToSend">The StunMessage to send to the connected STUN Server</param>
        /// <param name="transactionObject"></param>
        public void BeginSendMessage(StunMessage msgToSend, Object transactionObject)
        {
            if(msgToSend.MethodClass == StunMethodClass.Request)
                this.PendingTransactions.Add(msgToSend.TransactionID, new KeyValuePair<StunMessage, Object>(msgToSend, transactionObject));

            if (this.UseSsl)
                this.SslStream.BeginWrite(msgToSend, 0, msgToSend.Bytes.Length, new AsyncCallback(this.SendCallback), null);
            else
                this.Socket.BeginSend(msgToSend, 0, msgToSend.Bytes.Length, SocketFlags.None, new AsyncCallback(this.SendCallback), null);
        }
示例#13
0
        /// <summary>
        /// Sends a StunMessage to the connected STUN Server.
        /// </summary>
        /// <param name="msgToSend">The StunMessage to send to the connected STUN Server</param>
        /// <returns>The STUN Server response or null if msgToSend parameter is not a Request</returns>
        public StunMessage SendMessage(StunMessage msgToSend)
        {
            Boolean waitForResponse = msgToSend.MethodClass == StunMethodClass.Request;

            byte[] msgReceived = new byte[StunClient.BUFFER_SIZE];

            if (this.UseSsl)
            {
                this.SslStream.Write(msgToSend, 0, msgToSend.Bytes.Length);

                if (waitForResponse)
                    this.SslStream.Read(msgReceived, 0, StunClient.BUFFER_SIZE);
            }
            else
            {
                this.Socket.Send(msgToSend, 0, msgToSend.Bytes.Length, SocketFlags.None);

                if (waitForResponse)
                    this.Socket.Receive(msgReceived, 0, StunClient.BUFFER_SIZE, SocketFlags.None);
            }

            if (waitForResponse &&
                new ByteArrayComparer().Equals(((StunMessage)msgReceived).TransactionID, msgToSend.TransactionID))
            {
                return msgReceived;
            }

            return null;
        }
示例#14
0
        /// <summary>
        /// TODO: Documentation Allocate
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        public void Allocate(String username, String password)
        {
            StunMessage msg = new StunMessage(StunMethodType.Allocate, StunMethodClass.Request, StunUtilities.NewTransactionId);

            this.StunClient.BeginSendMessage(msg, new String[] { username, password });
        }
示例#15
0
        /// <summary>
        /// TODO: Documentation turnManager_OnAllocateSucceed
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="allocation"></param>
        /// <param name="sentMsg"></param>
        /// <param name="receivedMsg"></param>
        private void turnManager_OnAllocateSucceed(object sender, TurnAllocation allocation, StunMessage sentMsg, StunMessage receivedMsg)
        {
            if (this.StartingSessionRecipient != null)
            {
                this.turnSessions[this.StartingSessionSid].TurnAllocation = allocation;

                XmlDocument doc = new XmlDocument();

                // Jingle Transport
                JingleIce jingleIce = new JingleIce(doc)
                {
                    Pwd = JingleUtilities.GenerateIcePwd,
                    Ufrag = JingleUtilities.GenerateIceUfrag
                };

                if (this.OnIceCandidatesGathering != null)
                    this.OnIceCandidatesGathering(this, jingleIce, (sender as TurnManager).HostEP, this.turnSessions[this.StartingSessionSid].UseTurnOnly, allocation);

                this.localCandidates.Add(this.StartingSessionSid, jingleIce.GetCandidates());

                JingleIQ jingleIq = null;

                // Jingle Description
                Element jingleDescription = null;
                String contentName = null;

                if (this.OnDescriptionGathering != null)
                    this.OnDescriptionGathering(this, doc, this.StartingSessionSid, ref jingleDescription, ref contentName);

                jingleIq = this.JingleManager.SessionRequest(this.StartingSessionRecipient,
                                                             this.StartingSessionAction,
                                                             this.StartingSessionSid, contentName,
                                                             jingleDescription, jingleIce);

                //this.jingleManager.FindSession(this.StartingSessionSid).Local = jingleIq.Instruction;

                this.Stream.Write(jingleIq);
            }
        }
示例#16
0
        /// <summary>
        /// TODO: Documentation AllocateRetry
        /// </summary>
        /// <param name="receivedMsg"></param>
        /// <param name="username"></param>
        /// <param name="password"></param>
        private void AllocateRetry(StunMessage receivedMsg, String username, String password)
        {
            StunMessage msg = new StunMessage(StunMethodType.Allocate, StunMethodClass.Request, StunUtilities.NewTransactionId);

            msg.Turn.RequestedTransport = new StunAttribute(StunAttributeType.RequestedTransport, BitConverter.GetBytes(StunMessage.CODE_POINT_TCP));
            msg.Stun.Username = new UTF8Attribute(StunAttributeType.Username, username);
            msg.Stun.Realm = receivedMsg.Stun.Realm;
            msg.Stun.Nonce = receivedMsg.Stun.Nonce;

            msg.AddMessageIntegrity(password, true);

            this.StunClient.BeginSendMessage(msg, password);
        }
示例#17
0
        /// <summary>
        /// TODO: Documentation turnManager_OnAllocateFailed
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="receivedMsg"></param>
        /// <param name="sentMsg"></param>
        /// <param name="transactionObject"></param>
        private void turnManager_OnAllocateFailed(object sender, StunMessage receivedMsg, StunMessage sentMsg, object transactionObject)
        {
            if (this.StartingSessionRecipient != null)
            {
                if (this.OnConnectionTryEnded != null)
                    this.OnConnectionTryEnded(this, this.StartingSessionSid);

                this.DestroyTurnSession(this.StartingSessionSid);

                this.CancelStartingSession();
            }
        }
示例#18
0
        /// <summary>
        /// TODO: Documentation BindChannel
        /// </summary>
        /// <param name="channelNumber"></param>
        /// <param name="xorPeerAddress"></param>
        /// <param name="allocation"></param>
        public void BindChannel(byte[] channelNumber, XorMappedAddress xorPeerAddress, TurnAllocation allocation)
        {
            StunMessage msg = new StunMessage(StunMethodType.ChannelBind, StunMethodClass.Request, StunUtilities.NewTransactionId);

            msg.Turn.ChannelNumber = new StunAttribute(StunAttributeType.ChannelNumber, channelNumber);
            msg.Turn.XorPeerAddress = xorPeerAddress;
            msg.Stun.Username = new UTF8Attribute(StunAttributeType.Username, allocation.Username);
            msg.Stun.Realm = new UTF8Attribute(StunAttributeType.Realm, allocation.Realm);
            msg.Stun.Nonce = new UTF8Attribute(StunAttributeType.Nonce, allocation.Nonce);

            msg.AddMessageIntegrity(allocation.Password, true);

            this.StunClient.BeginSendMessage(msg, allocation);
        }
示例#19
0
 /// <summary>
 /// TODO: Documentation turnManager_OnConnectionAttemptReceived
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="receivedMsg"></param>
 private void turnManager_OnConnectionAttemptReceived(object sender, StunMessage receivedMsg)
 {
     (sender as TurnManager).ConnectionBind(receivedMsg.Turn.ConnectionId, this.TurnUsername, this.TurnPassword);
 }
示例#20
0
        /// <summary>
        /// TODO: Documentation ConnectionBind
        /// </summary>
        /// <param name="connectionId"></param>
        /// <param name="username"></param>
        /// <param name="password"></param>
        public void ConnectionBind(StunAttribute connectionId, String username, String password)
        {
            this.TurnTcpManager = new TurnManager(this.StunClient.ServerEP,
                                                  this.StunClient.ProtocolType,
                                                  this.StunClient.ClientCertificate,
                                                  this.StunClient.RemoteCertificateValidation);

            this.TurnTcpManager.OnAllocateSucceed += (object sender, TurnAllocation allocation, StunMessage sentMsg, StunMessage receivedMsg) =>
                {
                    StunMessage msg = new StunMessage(StunMethodType.ConnectionBind, StunMethodClass.Request, StunUtilities.NewTransactionId);

                    msg.Turn.ConnectionId = connectionId;
                    msg.Stun.Username = new UTF8Attribute(StunAttributeType.Username, allocation.Username);
                    msg.Stun.Realm = new UTF8Attribute(StunAttributeType.Realm, allocation.Realm);
                    msg.Stun.Nonce = new UTF8Attribute(StunAttributeType.Nonce, allocation.Nonce);

                    msg.AddMessageIntegrity(allocation.Password, true);

                    this.TurnTcpManager.StunClient.BeginSendMessage(msg, this.TurnTcpManager.StunClient.Socket);
                };

            this.TurnTcpManager.OnConnectionBindSucceed += (object sender, Socket connectedSocket, StunMessage receivedMsg) =>
                {
                    this.TurnTcpManager.Allocations.Clear();
                    this.TurnTcpManager.StunClient.Cancel = true;

                    if (this.OnConnectionBindSucceed != null)
                        this.OnConnectionBindSucceed(sender, connectedSocket, receivedMsg);
                };

            this.TurnTcpManager.Connect();
            this.TurnTcpManager.Allocate(username, password);
        }
示例#21
0
        /// <summary>
        /// TODO: Documentation ReceiveCallback
        /// </summary>
        /// <param name="ar"></param>
        private void ReceiveCallback(IAsyncResult ar)
        {
            byte[] state = (byte[])ar.AsyncState;

            try
            {
                Int32 bytesReceived;

                if (this.UseSsl)
                {
                    bytesReceived = this.SslStream.EndRead(ar);
                }
                else
                {
                    bytesReceived = this.Socket.EndReceive(ar);
                }


                if (bytesReceived > 0)
                {
                    StunMessage receivedMsg = state;

                    KeyValuePair <StunMessage, Object> transactionObject = new KeyValuePair <StunMessage, Object>();

                    switch (receivedMsg.MethodClass)
                    {
                    case StunMethodClass.SuccessResponse:
                        if (!this.IsPendingTransaction(receivedMsg.TransactionID, out transactionObject))
                        {
                            return;
                        }

                        if (this.OnReceivedSuccessResponse != null)
                        {
                            this.OnReceivedSuccessResponse(this, receivedMsg, transactionObject.Key, transactionObject.Value);
                        }
                        break;

                    case StunMethodClass.Indication:
                        if (this.OnReceivedIndication != null)
                        {
                            this.OnReceivedIndication(this, receivedMsg);
                        }
                        break;

                    case StunMethodClass.Error:
                        if (!this.IsPendingTransaction(receivedMsg.TransactionID, out transactionObject))
                        {
                            return;
                        }

                        if (this.OnReceivedError != null)
                        {
                            this.OnReceivedError(this, receivedMsg, transactionObject.Key, transactionObject.Value);
                        }
                        break;
                    }

                    byte[] result = new byte[StunClient.BUFFER_SIZE];

                    if (this.Socket != null && !this.Cancel)
                    {
                        if (this.UseSsl)
                        {
                            this.SslStream.BeginRead(result, 0, result.Length, new AsyncCallback(this.ReceiveCallback), result);
                        }
                        else
                        {
                            this.Socket.BeginReceive(result, 0, result.Length, SocketFlags.None, new AsyncCallback(this.ReceiveCallback), result);
                        }
                    }
                }
                else
                {
                    if (!this.isDisconnecting)
                    {
                        this.Disconnect();
                    }
                }
            }
            catch (Exception ex)
            {
                if (!this.isDisconnecting)
                {
                    this.Disconnect();
                }
            }
        }