예제 #1
0
        private byte[] AddIndicationHeader(STUNAddress stunAddress, byte[] data)
        {
            // send indication
            MessageSTUN message = CreateMessageSTUN(STUNMethod.DataIndication);

            byte[] ret;
            if (stunAddress.IsIPv4)
            {
                ret    = new byte[8];
                ret[1] = (byte)(0x01); // family
            }
            else
            {
                ret    = new byte[16];
                ret[1] = (byte)(0x02); // family
            }
            ret[0] = (byte)(0x0);

            ret[3]  = (byte)(stunAddress.port & 0xff);
            ret[2]  = (byte)((stunAddress.port >> 8) & 0xff);
            ret[2] ^= transactionID[0];
            ret[3] ^= transactionID[1];

            for (int i = 0; i < stunAddress.address.Length; i++)
            {
                ret[4 + i] = (byte)(stunAddress.address[i] ^ transactionID[i]);
            }

            message.WriteBytes(STUNAttribute.XorPeerAddress, ret);
            message.WriteEmpty(STUNAttribute.DontFragment);
            message.WriteBytes(STUNAttribute.Data, data);
            return(message.WriteRequest());
        }
예제 #2
0
        public byte[] Translate(STUNAddress peer, string text)
        {
            byte[] utfBytes  = Encoding.UTF8.GetBytes(text);
            string ipaddress = peer.ToString();

            return(Translate(ipaddress, utfBytes));
        }
예제 #3
0
        public STUNAddress ReadMappedAddress()
        {
            STUNAddress sa         = new STUNAddress();
            ushort      attrLength = serializer.ReadUShort();
            byte        empty      = serializer.ReadByte();

            sa.family = serializer.ReadByte();
            sa.port   = serializer.ReadUShort();

            switch (sa.family)
            {
            case 1:
                sa.address = new byte[4];
                break;

            case 2:
                sa.address = new byte[16];
                break;
            }

            for (int i = 0; i < sa.address.Length; i++)
            {
                sa.address[i] = serializer.ReadByte();
            }
            return(sa);
        }
예제 #4
0
 public bool TranslateSend(STUNAddress ip, string text)
 {
     if (!usingSTUN || stunCore == null)
     {
         //throw new Exception("Turn service is Off");
         return(false);
     }
     return(base.Send(stunCore.Translate(ip, text)) > 0);
 }
예제 #5
0
 public bool TranslateSend(STUNAddress ip, byte[] datas)
 {
     if (!usingSTUN || stunCore == null)
     {
         //throw new Exception("Turn service is Off");
         return(false);
     }
     datas = stunCore.Translate(ip, datas);
     return(base.Send(datas) > 0);
 }
예제 #6
0
        public void RequestChannelBind(STUNAddress stunAddress)
        {
            lock (_lock)
            {
                MessageSTUN message = CreateMessageSTUN(STUNMethod.ChannelBindRequest);
                // channel number [0x4000 through 0x4FFF](uint)random.Next(0x4001, 0x4FFF);
                uint channelNumber;
                if (!ip2ChannelNumber.ContainsKey(stunAddress.ToString()))
                {
                    GenerateChannelNumberForPeer(stunAddress);
                }
                channelNumber = ip2ChannelNumber[stunAddress.ToString()];
                Console.WriteLine("RequestChannelBind: {0} {1}:{2}", channelNumber, stunAddress.ToString(), stunAddress.port);
                channelNumber = (uint)(channelNumber << 16);
                message.WriteString(STUNAttribute.Username, message.username);
                message.WriteString(STUNAttribute.Realm, message.realm);

                message.WriteUInt(STUNAttribute.ChannelNumber, channelNumber);

                byte[] ret;
                if (stunAddress.IsIPv4)
                {
                    ret    = new byte[8];
                    ret[1] = (byte)(0x01); // family
                }
                else
                {
                    ret    = new byte[16];
                    ret[1] = (byte)(0x02); // family
                }
                ret[0] = (byte)(0x0);

                ret[3]  = (byte)(stunAddress.port & 0xff);
                ret[2]  = (byte)((stunAddress.port >> 8) & 0xff);
                ret[2] ^= transactionID[0];
                ret[3] ^= transactionID[1];

                for (int i = 0; i < stunAddress.address.Length; i++)
                {
                    ret[4 + i] = (byte)(stunAddress.address[i] ^ transactionID[i]);
                }

                message.WriteBytes(STUNAttribute.XorPeerAddress, ret);
                if (nonce != null)
                {
                    message.WriteBytes(STUNAttribute.Nonce, nonce);
                    message.WriteRequestIntegrity();
                }
                byte[] pkg = message.WriteRequest();
                sender.Send(pkg);
            }
        }
예제 #7
0
        public virtual void OnAllocateResponse(MessageSTUN message)
        {
            lock (_lock)
            {
                ip2ChannelNumber.Clear();
                channelNumber2Peer.Clear();
            }
            GenerateChannelNumberForAllPeers();
            RequestRefreshAllBindingChannelLifeTime();
            StartRefreshTimer();
            StartCheckingConnectionTimer();

            STUNAddress sa = (STUNAddress)message.Get(STUNAttribute.XorRelayedAddress);

            //OnServerDataReceived?.BeginInvoke(this, new STUN_ServerDataReceivedEventArgs((int)responseChannelNumber, new ArraySegment<byte>(appData)), EndAsyncEvent, null);
            OnAllocateResponseEvent?.Invoke(this, new NATP_SignalingEventArgs(true, "", new IPEndPoint(new IPAddress(sa.address), sa.port)));
        }
예제 #8
0
        public void RequestCreatePermission(STUNAddress stunAddress)
        {
            lock (_lock)
            {
                MessageSTUN message = CreateMessageSTUN(STUNMethod.CreatePermissionRequest);
                message.WriteString(STUNAttribute.Username, message.username);
                message.WriteString(STUNAttribute.Realm, message.realm);

                byte[] ret;
                if (stunAddress.IsIPv4)
                {
                    ret    = new byte[8];
                    ret[1] = (byte)(0x01); // family
                }
                else
                {
                    ret    = new byte[16];
                    ret[1] = (byte)(0x02); // family
                }
                ret[0] = (byte)(0x0);
                ushort xorFlag16 = (ushort)(magicCookie >> 16);

                ret[3]  = 0;
                ret[2]  = 0;
                ret[2] ^= transactionID[0];
                ret[3] ^= transactionID[1];

                for (int i = 0; i < stunAddress.address.Length; i++)
                {
                    ret[4 + i] = (byte)(stunAddress.address[i] ^ transactionID[i]);
                }

                message.WriteBytes(STUNAttribute.XorPeerAddress, ret);
                if (nonce != null)
                {
                    message.WriteBytes(STUNAttribute.Nonce, nonce);
                    message.WriteRequestIntegrity();
                }
                byte[] pkg = message.WriteRequest();
                sender.Send(pkg);
            }
        }
예제 #9
0
        private uint GenerateChannelNumberForPeer(STUNAddress peer)
        {
            string key = peer.ToString();

            lock (_lock)
            {
                if (ip2ChannelNumber.ContainsKey(key))
                {
                    return(ip2ChannelNumber[key]);
                }
                // channel number [0x4000 through 0x4FFF]
                while (channelNumber2Peer.ContainsKey(channelNumberAvailalbe))
                {
                    AddChannelNumberAvailalbe();
                }
                channelNumber2Peer[channelNumberAvailalbe] = peer;
                uint channelnumber = channelNumberAvailalbe;
                ip2ChannelNumber[key] = channelNumberAvailalbe;
                AddChannelNumberAvailalbe();
                return(channelnumber);
            }
        }
예제 #10
0
        public STUNAddress ReadXorMappedAddress()
        {
            STUNAddress sa         = new STUNAddress();
            ushort      attrLength = serializer.ReadUShort();
            ushort      xorFlag16  = (ushort)(magicCookie >> 16);
            byte        empty      = serializer.ReadByte();

            sa.family = serializer.ReadByte();
            sa.port   = (ushort)(serializer.ReadUShort() ^ xorFlag16);

            switch (sa.family)
            {
            case 1:
                byte[] xorFlagBytes = new byte[4];
                Array.Copy(serializer.ByteBuffer, 4, xorFlagBytes, 0, 4);
                Array.Reverse(xorFlagBytes);
                uint xorFlag32 = BitConverter.ToUInt32(xorFlagBytes, 0);

                sa.address = new byte[4];
                uint address = serializer.ReadUInt() ^ xorFlag32;
                sa.address[0] = (byte)((address & 0xff000000) >> 24);
                sa.address[1] = (byte)((address & 0x00ff0000) >> 16);
                sa.address[2] = (byte)((address & 0x0000ff00) >> 8);
                sa.address[3] = (byte)(address & 0x000000ff);
                break;

            case 2:
                sa.address = new byte[16];
                byte[] xorFlags = new byte[16];
                Array.Copy(transactionID, 0, xorFlags, xorFlags.Length, transactionID.Length);
                for (int i = 0; i < sa.address.Length; i++)
                {
                    sa.address[i] = (byte)(serializer.ReadByte() ^ xorFlags[i]);
                }
                break;
            }

            return(sa);
        }
예제 #11
0
        private bool AddPeer(STUNAddress addr)
        {
            lock (_lock)
            {
                if (ip2ChannelNumber.ContainsKey(addr.ToString()))
                {
                    return(false);
                }
            }
            peers.Add(addr);
            var id = GenerateChannelNumberForPeer(addr);

            lock (_lockHeartbeat)
            {
                peerHeartbeat[id] = -2;// (int)((double)lifeTime / (double)STUNClient.HeartbeatAfterConnected + 0.5);
            }

            if (peersInTrashCan.ContainsKey(id))
            {
                peersInTrashCan.Remove(id);
            }
            return(true);
        }
예제 #12
0
 public byte[] Translate(STUNAddress ipaddress, byte[] data)
 {
     return(Translate(ipaddress.ToString(), data));
 }