Example #1
0
        public Allocation Get(ConnectionId connectionId)
        {
            Allocation allocation = null;

            lock (syncRoot)
                allocations3.TryGetValue(connectionId, out allocation);

            return(allocation != null && allocation.IsValid() ? allocation : null);
        }
Example #2
0
        public Allocation GetByPeer(ServerEndPoint local, IPEndPoint remote)
        {
            Allocation allocation = null;

            lock (syncRoot)
                allocations4.TryGetValue(GetKey(local, remote), out allocation);

            return(allocation != null && allocation.IsValid() ? allocation : null);
        }
Example #3
0
        public Allocation Get(TransactionId transactionId)
        {
            Allocation allocation = null;

            lock (syncRoot)
                allocations1.TryGetValue(transactionId, out allocation);

            return(allocation != null && allocation.IsValid() ? allocation : null);
        }
Example #4
0
        public void Remove(Allocation oldAllocation, RemoveReason reason)
        {
            lock (syncRoot)
            {
                byAllocated.Remove(oldAllocation.Alocated);
                byReal.Remove(oldAllocation.Real);
                byConnectionId.Remove(oldAllocation.ConnectionId);
                byKey.Remove(GetKey(oldAllocation.Local, oldAllocation.Reflexive));
            }

            OnRemoved(oldAllocation, reason);
        }
Example #5
0
        public void Remove(Allocation oldAllocation)
        {
            lock (syncRoot)
            {
                allocations1.Remove(oldAllocation.TransactionId);
                byAllocated.Remove(oldAllocation.Alocated);
                allocations3.Remove(oldAllocation.ConnectionId);
                allocations4.Remove(GetKey(oldAllocation.Local, oldAllocation.Reflexive));
            }

            OnRemoved(oldAllocation);
        }
Example #6
0
        public Allocation Get(ServerEndPoint allocated)
        {
            Allocation allocation = null;

            lock (syncRoot)
            {
                if (byAllocated.TryGetValue(allocated, out allocation) == false)
                {
                    byReal.TryGetValue(allocated, out allocation);
                }
            }

            return(allocation != null && allocation.IsValid() ? allocation : null);
        }
Example #7
0
        private void OnRemoved(Allocation allocation)
        {
#if DEBUG
            try
            {
                Monitor.Exit(syncRoot);
                throw new Exception("Deadlock Warning!");
            }
            catch (SynchronizationLockException)
            {
            }
#endif

            Removed(allocation);
        }
Example #8
0
        private TurnMessage ProcessSetActiveDestinationRequest(Allocation allocation, TurnMessage request, IPEndPoint reflexEndPoint)
        {
            if (allocation == null)
            {
                throw new TurnServerException(ErrorCode.NoBinding);
            }

            if (request.DestinationAddress == null)
            {
                throw new TurnServerException(ErrorCode.BadRequest);
            }

            allocation.ActiveDestination = request.DestinationAddress.IpEndPoint;
            allocation.Permissions.Permit(request.DestinationAddress.IpEndPoint);

            logger.WriteInformation(string.Format("Set Active Destination: {2} --> {0} <--> {1}", allocation.Alocated.ToString(), allocation.Reflexive.ToString(), allocation.ActiveDestination.ToString()));

            uint sequenceNumber = (request.MsSequenceNumber != null) ? request.MsSequenceNumber.SequenceNumber : 0;

            return(new TurnMessage()
            {
                IsAttributePaddingDisabled = true,
                MessageType = MessageType.SetActiveDestinationResponse,
                TransactionId = request.TransactionId,

                MagicCookie = new MagicCookie(),

                Realm = new Realm(TurnMessageRfc.MsTurn)
                {
                    Ignore = true,
                    Value = Authentificater.Realm,
                },
                MsUsername = new MsUsername()
                {
                    Ignore = true,
                    Value = request.MsUsername.Value,
                },
                //MsUsername = allocation.Username,
                MessageIntegrity = new MessageIntegrity(),

                MsSequenceNumber = new MsSequenceNumber()
                {
                    ConnectionId = allocation.ConnectionId,
                    SequenceNumber = sequenceNumber,//allocation.SequenceNumber,
                },
            });
        }
Example #9
0
        public void Clear()
        {
            Allocation[] removeList = null;

            lock (syncRoot)
            {
                if (byAllocated.Values.Count > 0)
                {
                    removeList = new Allocation[byAllocated.Values.Count];
                    byAllocated.Values.CopyTo(removeList, 0);
                }

                byAllocated.Clear();
                byReal.Clear();
                byConnectionId.Clear();
                byKey.Clear();
            }

            if (removeList != null)
                foreach (var allocation in removeList)
                    OnRemoved(allocation, RemoveReason.Stopping);
        }
Example #10
0
        public void Replace(Allocation allocation)
        {
            Allocation oldAllocation;

            lock (syncRoot)
            {
                var key = GetKey(allocation.Local, allocation.Reflexive);

                if (byKey.TryGetValue(key, out oldAllocation))
                {
                    byAllocated.Remove(oldAllocation.Alocated);
                    byReal.Remove(oldAllocation.Real);
                    byConnectionId.Remove(oldAllocation.ConnectionId);
                    byKey.Remove(key);
                }

                byAllocated.Add(allocation.Alocated, allocation);
                byReal.Add(allocation.Real, allocation);
                byConnectionId.Add(allocation.ConnectionId, allocation);
                byKey.Add(key, allocation);
            }

            if (oldAllocation != null)
                OnRemoved(oldAllocation, RemoveReason.Replace);
        }
Example #11
0
        public void Remove(Allocation oldAllocation, RemoveReason reason)
        {
            lock (syncRoot)
            {
                byAllocated.Remove(oldAllocation.Alocated);
                byReal.Remove(oldAllocation.Real);
                byConnectionId.Remove(oldAllocation.ConnectionId);
                byKey.Remove(GetKey(oldAllocation.Local, oldAllocation.Reflexive));
            }

            OnRemoved(oldAllocation, reason);
        }
Example #12
0
        private void TurnServer_TurnDataReceived(ref ServerAsyncEventArgs e)
        {
            //lock (syncRoot)
            {
                TurnMessage response = null;

                try
                {
                    if (true)//(TransactionServer.GetCachedResponse(e, out response) == false)
                    {
                        TurnMessage request = TurnMessage.Parse(e.Buffer, e.Offset, e.BytesTransferred, TurnMessageRfc.MsTurn);

                        if (Authentificater.Process(request, out response))
                        {
                            Allocation allocation = null;
                            if (request.MsSequenceNumber != null)
                            {
                                allocation = allocations.Get(request.MsSequenceNumber.ConnectionId);
                            }

                            if (allocation != null)
                            {
                                if (request.MsSequenceNumber != null)
                                {
                                    response = allocation.GetResponse(request.MsSequenceNumber.SequenceNumber);
                                }
                            }

                            if (response == null)
                            {
                                if (allocation != null)
                                {
                                    allocation.TouchLifetime();
                                }

                                switch (request.MessageType)
                                {
                                case MessageType.AllocateRequest:
                                    response = ProcessAllocateRequest(ref allocation, request, e.LocalEndPoint, e.RemoteEndPoint);
                                    break;

                                case MessageType.SendRequest:
                                    response = ProcessSendRequest(allocation, request, ref e);
                                    break;

                                case MessageType.SetActiveDestinationRequest:
                                    response = ProcessSetActiveDestinationRequest(allocation, request, e.RemoteEndPoint);
                                    break;
                                }

                                if (allocation != null && response != null)
                                {
                                    allocation.SetResponse(response);
                                }
                            }
                        }

                        //TransactionServer.CacheResponse(e, response);
                    }
                }
                catch (TurnMessageException ex)
                {
                    response = GetErrorResponse(ex.ErrorCode, e);
                }
                catch (TurnServerException ex)
                {
                    response = GetErrorResponse(ex.ErrorCode, e);
                }
                catch (Exception ex)
                {
                    response = GetErrorResponse(ErrorCode.ServerError, e);

                    logger.WriteError(ex.ToString());
                }

                if (response != null)
                {
                    SendTurn(response, e.LocalEndPoint, e.RemoteEndPoint);
                }
            }
        }
Example #13
0
        private TurnMessage ProcessSendRequest(Allocation allocation, TurnMessage request, ref ServerAsyncEventArgs e)
        {
            try
            {
                if (allocation == null)
                    throw new TurnServerException(ErrorCode.NoBinding);

                if (request.Data == null || request.DestinationAddress == null)
                    throw new TurnServerException(ErrorCode.BadRequest);

                allocation.Permissions.Permit(request.DestinationAddress.IpEndPoint);

                e.LocalEndPoint = allocation.Alocated;
                e.RemoteEndPoint = request.DestinationAddress.IpEndPoint;
                e.Offset = request.Data.ValueRefOffset;
                e.Count = request.Data.ValueRefLength;
                e.ConnectionId = ServerAsyncEventArgs.AnyNewConnectionId;

                peerServer.SendAsync(e);

                e = null;
            }
            catch (Exception ex)
            {
                logger.WriteWarning(ex.ToString());
            }

            // [MS-TURN] The server MUST NOT respond to a client with either
            // a Send response or a Send error response.
            return null;
        }
Example #14
0
 private void Allocation_Removed(Allocation allocation, AllocationsPool.RemoveReason reason)
 {
     logger.WriteInformation(string.Format("Allocation Terminated: {0} <--> {1}, {2}", allocation.Alocated.ToString(), allocation.Reflexive.ToString(), reason.ToString()));
     peerServer.Unbind(allocation.Alocated.ProtocolPort);
 }
Example #15
0
 private void Allocation_Removed(Allocation allocation)
 {
     peerServer.Unbind(allocation.Alocated.ProtocolPort);
 }
Example #16
0
 private void OnRemoved(Allocation allocation, RemoveReason reason)
 {
     Removed(allocation, reason);
 }
Example #17
0
        private bool PeerServer_Received(ServersManager <PeerConnection> s, BaseConnection с, ref ServerAsyncEventArgs e)
        {
            //lock (syncRoot)
            {
                try
                {
                    Allocation allocation = allocations.Get(e.LocalEndPoint);

                    if (allocation != null)
                    {
                        if (allocation.Permissions.IsPermited(e.RemoteEndPoint))
                        {
                            allocation.TouchLifetime();

                            if (allocation.ActiveDestination.IsEqual(e.RemoteEndPoint))
                            {
                                if (e.LocalEndPoint.Protocol == ServerProtocol.Tcp)
                                {
                                    TcpFramingHeader.GetBytes(e.Buffer, e.Offset, TcpFrameType.EndToEndData, e.BytesTransferred);

                                    e.Count        = e.OffsetOffset + e.BytesTransferred;
                                    e.OffsetOffset = 0;
                                }
                                else
                                {
                                    e.Count = e.BytesTransferred;
                                }

                                e.LocalEndPoint  = allocation.Local;
                                e.RemoteEndPoint = allocation.Reflexive;
                                e.ConnectionId   = ServerAsyncEventArgs.AnyConnectionId;

                                turnServer.SendAsync(e);

                                e = null;
                            }
                            else
                            {
                                TurnMessage message = new TurnMessage()
                                {
                                    IsAttributePaddingDisabled = true,
                                    MessageType   = MessageType.DataIndication,
                                    TransactionId = TransactionServer.GenerateTransactionId(),

                                    MagicCookie = new MagicCookie(),

                                    RemoteAddress = new RemoteAddress()
                                    {
                                        IpAddress = e.RemoteEndPoint.Address,
                                        Port      = (UInt16)e.RemoteEndPoint.Port,
                                    },

                                    Data = new Data()
                                    {
                                        ValueRef       = e.Buffer,
                                        ValueRefOffset = e.Offset,
                                        ValueRefLength = e.BytesTransferred,
                                    },
                                };

                                SendTurn(message, allocation.Local, allocation.Reflexive);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    logger.WriteWarning(ex.ToString());
                }
            }

            return(true);
        }
Example #18
0
 private void Allocation_Removed(Allocation allocation, AllocationsPool.RemoveReason reason)
 {
     logger.WriteInformation(string.Format("Allocation Terminated: {0} <--> {1}, {2}", allocation.Alocated.ToString(), allocation.Reflexive.ToString(), reason.ToString()));
     peerServer.Unbind(allocation.Alocated.ProtocolPort);
 }
Example #19
0
        private TurnMessage ProcessAllocateRequest(ref Allocation allocation, TurnMessage request, ServerEndPoint local, IPEndPoint remote)
        {
            uint sequenceNumber = (request.MsSequenceNumber != null) ? request.MsSequenceNumber.SequenceNumber : 0;

            {
                uint lifetime = (request.Lifetime != null) ? ((request.Lifetime.Value > MaxLifetime.Seconds) ? MaxLifetime.Seconds : request.Lifetime.Value) : DefaultLifetime.Seconds;

                if (allocation != null)
                {
                    allocation.Lifetime = lifetime;

                    if (lifetime == 0)
                        logger.WriteInformation(string.Format("Update Allocation: {2} seconds {0} <--> {1}", allocation.Alocated.ToString(), allocation.Reflexive.ToString(), lifetime));
                }
                else
                {
                    if (lifetime <= 0)
                        throw new TurnServerException(ErrorCode.NoBinding);

                    ProtocolPort pp = new ProtocolPort() { Protocol = local.Protocol, };
                    if (peerServer.Bind(ref pp) != SocketError.Success)
                        throw new TurnServerException(ErrorCode.ServerError);

                    allocation = new Allocation()
                    {
                        TransactionId = request.TransactionId,
                        ConnectionId = ConnectionIdGenerator.Generate(local, remote),

                        Local = local,
                        Alocated = new ServerEndPoint(pp, PublicIp),
                        Real = new ServerEndPoint(pp, RealIp),
                        Reflexive = new IPEndPoint(remote.Address, remote.Port),

                        Lifetime = lifetime,
                    };

                    allocations.Replace(allocation);

                    logger.WriteInformation(string.Format("Allocated: {0} <--> {1} for {2} seconds", allocation.Alocated.ToString(), allocation.Reflexive.ToString(), allocation.Lifetime));
                }
            }

            return new TurnMessage()
            {
                IsAttributePaddingDisabled = true,
                MessageType = MessageType.AllocateResponse,
                TransactionId = request.TransactionId,

                MagicCookie = new MagicCookie(),

                MappedAddress = new MappedAddress()
                {
                    IpAddress = allocation.Alocated.Address,
                    Port = (UInt16)allocation.Alocated.Port,
                },

                Lifetime = new Lifetime() { Value = allocation.Lifetime, },
                Bandwidth = new Bandwidth() { Value = 750, },

                XorMappedAddress = new XorMappedAddress(TurnMessageRfc.MsTurn)
                {
                    IpAddress = remote.Address,
                    Port = (UInt16)remote.Port,
                },

                Realm = new Realm(TurnMessageRfc.MsTurn)
                {
                    Ignore = true,
                    Value = Authentificater.Realm,
                },
                MsUsername = new MsUsername()
                {
                    Ignore = true,
                    Value = request.MsUsername.Value,
                },
                //MsUsername = allocation.Username,
                MessageIntegrity = new MessageIntegrity(),

                MsSequenceNumber = new MsSequenceNumber()
                {
                    ConnectionId = allocation.ConnectionId,
                    SequenceNumber = sequenceNumber,//allocation.SequenceNumber,
                },
            };
        }
Example #20
0
        private TurnMessage ProcessAllocateRequest(ref Allocation allocation, TurnMessage request, ServerEndPoint local, IPEndPoint remote)
        {
            uint sequenceNumber = (request.MsSequenceNumber != null) ? request.MsSequenceNumber.SequenceNumber : 0;

            {
                uint lifetime = (request.Lifetime != null) ? ((request.Lifetime.Value > MaxLifetime.Seconds) ? MaxLifetime.Seconds : request.Lifetime.Value) : DefaultLifetime.Seconds;

                if (allocation != null)
                {
                    allocation.Lifetime = lifetime;

                    if (lifetime == 0)
                    {
                        logger.WriteInformation(string.Format("Update Allocation: {2} seconds {0} <--> {1}", allocation.Alocated.ToString(), allocation.Reflexive.ToString(), lifetime));
                    }
                }
                else
                {
                    if (lifetime <= 0)
                    {
                        throw new TurnServerException(ErrorCode.NoBinding);
                    }

                    ProtocolPort pp = new ProtocolPort()
                    {
                        Protocol = local.Protocol,
                    };
                    if (peerServer.Bind(ref pp) != SocketError.Success)
                    {
                        throw new TurnServerException(ErrorCode.ServerError);
                    }

                    allocation = new Allocation()
                    {
                        TransactionId = request.TransactionId,
                        ConnectionId  = ConnectionIdGenerator.Generate(local, remote),

                        Local     = local,
                        Alocated  = new ServerEndPoint(pp, PublicIp),
                        Real      = new ServerEndPoint(pp, RealIp),
                        Reflexive = new IPEndPoint(remote.Address, remote.Port),

                        Lifetime = lifetime,
                    };

                    allocations.Replace(allocation);

                    logger.WriteInformation(string.Format("Allocated: {0} <--> {1} for {2} seconds", allocation.Alocated.ToString(), allocation.Reflexive.ToString(), allocation.Lifetime));
                }
            }

            return(new TurnMessage()
            {
                IsAttributePaddingDisabled = true,
                MessageType = MessageType.AllocateResponse,
                TransactionId = request.TransactionId,

                MagicCookie = new MagicCookie(),

                MappedAddress = new MappedAddress()
                {
                    IpAddress = allocation.Alocated.Address,
                    Port = (UInt16)allocation.Alocated.Port,
                },

                Lifetime = new Lifetime()
                {
                    Value = allocation.Lifetime,
                },
                Bandwidth = new Bandwidth()
                {
                    Value = 750,
                },

                XorMappedAddress = new XorMappedAddress(TurnMessageRfc.MsTurn)
                {
                    IpAddress = remote.Address,
                    Port = (UInt16)remote.Port,
                },

                Realm = new Realm(TurnMessageRfc.MsTurn)
                {
                    Ignore = true,
                    Value = Authentificater.Realm,
                },
                MsUsername = new MsUsername()
                {
                    Ignore = true,
                    Value = request.MsUsername.Value,
                },
                //MsUsername = allocation.Username,
                MessageIntegrity = new MessageIntegrity(),

                MsSequenceNumber = new MsSequenceNumber()
                {
                    ConnectionId = allocation.ConnectionId,
                    SequenceNumber = sequenceNumber,//allocation.SequenceNumber,
                },
            });
        }
Example #21
0
        private TurnMessage ProcessSetActiveDestinationRequest(Allocation allocation, TurnMessage request, IPEndPoint reflexEndPoint)
        {
            if (allocation == null)
                throw new TurnServerException(ErrorCode.NoBinding);

            if (request.DestinationAddress == null)
                throw new TurnServerException(ErrorCode.BadRequest);

            allocation.ActiveDestination = request.DestinationAddress.IpEndPoint;
            allocation.Permissions.Permit(request.DestinationAddress.IpEndPoint);

            logger.WriteInformation(string.Format("Set Active Destination: {2} --> {0} <--> {1}", allocation.Alocated.ToString(), allocation.Reflexive.ToString(), allocation.ActiveDestination.ToString()));

            uint sequenceNumber = (request.MsSequenceNumber != null) ? request.MsSequenceNumber.SequenceNumber : 0;

            return new TurnMessage()
            {
                IsAttributePaddingDisabled = true,
                MessageType = MessageType.SetActiveDestinationResponse,
                TransactionId = request.TransactionId,

                MagicCookie = new MagicCookie(),

                Realm = new Realm(TurnMessageRfc.MsTurn)
                {
                    Ignore = true,
                    Value = Authentificater.Realm,
                },
                MsUsername = new MsUsername()
                {
                    Ignore = true,
                    Value = request.MsUsername.Value,
                },
                //MsUsername = allocation.Username,
                MessageIntegrity = new MessageIntegrity(),

                MsSequenceNumber = new MsSequenceNumber()
                {
                    ConnectionId = allocation.ConnectionId,
                    SequenceNumber = sequenceNumber,//allocation.SequenceNumber,
                },
            };
        }
Example #22
0
 private void OnRemoved(Allocation allocation, RemoveReason reason)
 {
     Removed(allocation, reason);
 }