예제 #1
0
        public static async UniTask <CheckRoomResponse> CheckRoomAsync()
        {
            var req = new CheckRoomRequest
            {
                peerid = UniP2PManager.MyPeerID,
                roomid = CurrentRoomID,
                token  = CurrentToken
            };

            req.SetHash();
            var result = await HttpClient.Post(GetURIGamekey(UniP2PManager.MatchingSettings.MatchingServerURI) + "/rooms/check", JsonUtility.ToJson(req));

            if (result.StatusCode == 200)
            {
                var room = JsonUtility.FromJson <CheckRoomResponse>(result.Text);
                foreach (var p in room.peers)
                {
                    if (p.id != UniP2PManager.MyPeerID && UniP2PManager.GetConnectedPeer(p.id) == null)
                    {
                        await UniP2PManager.SendEmptyPacketAsync(IPEndPointParser.Parse(p.ip));
                    }
                }
                return(room);
            }
            else
            {
                Debug.Debugger.Warning("[SimpleMatchingClient] CheckRoomAsync StatusCode:" + result.StatusCode + ":" + JsonUtility.ToJson(req));
                return(null);
            }
        }
예제 #2
0
 public static async UniTask JoinRoom(MatchingLANPacket info)
 {
     foreach (var ip in info.PeerIPEndPoints)
     {
         await UniP2PManager.ConnectPeerAsync(IPEndPointParser.Parse(ip));
     }
 }
예제 #3
0
        public void Open(string endPointAddress)
        {
            var endPoint = IPEndPointParser.Parse(endPointAddress);

            client = new TcpClient();
            client.Client.Connect(endPoint);
        }
예제 #4
0
        public PeerEndPoint(Stream s)
            : base(0, 0)
        {
            IPEndPoint ep = IPEndPointParser.Parse(s);

            this.Address = ep.Address;
            this.Port    = ep.Port;
        }
 public IPEndPoint Parse(string argName, string value, CultureInfo culture)
 {
     try
     {
         return(IPEndPointParser.Parse(value, 0));
     }
     catch (Exception ex)
     {
         throw new FormatException(ex.Message);
     }
 }
        /// <summary>
        /// IP end point format: "IP:Port number".
        /// IPV6 formats: [xx:xx:xx:xx:xx:xx:xx:xx]:port number, [xx:xx:xx:xx:xx:xx:xx:xx], xx:xx:xx:xx:xx:xx:xx:xx.
        /// IPV4 formats: x.x.x.x:port number, x.x.x.x.
        /// Extract IP address from "IP:Port number" end point format.
        /// </summary>
        private static string ExtractIpAddress(string endPoint)
        {
            IPAddress ipAddress = null;

            if (IPEndPointParser.TryParse(endPoint, out IPEndPoint ipEndPoint))
            {
                ipAddress = ipEndPoint.Address;
            }

            return(ipAddress?.ToString());
        }
예제 #7
0
        public void TestInvalid()
        {
            IPEndPoint ep;

            Assert.False(IPEndPointParser.TryParse(null, out ep));
            Assert.False(IPEndPointParser.TryParse("", out ep));
            Assert.False(IPEndPointParser.TryParse("132", out ep));
            Assert.False(IPEndPointParser.TryParse("300.0.0.1:1000", out ep));
            Assert.False(IPEndPointParser.TryParse("gggg::1", out ep));
            Assert.False(IPEndPointParser.TryParse("127.0.0.1:-1", out ep));
            Assert.False(IPEndPointParser.TryParse("::1:70000", out ep));
        }
예제 #8
0
        public static BinaryNumber GetNodeID(IPEndPoint nodeEP)
        {
            using (HMAC hmac = new HMACSHA1(NODE_ID_SALT))
            {
                using (MemoryStream mS = new MemoryStream(20))
                {
                    IPEndPointParser.WriteTo(nodeEP, mS);
                    mS.Position = 0;

                    return(new BinaryNumber(hmac.ComputeHash(mS)));
                }
            }
        }
예제 #9
0
        public IPEndPoint EndPoint()
        {
            if (string.IsNullOrWhiteSpace(Host))
            {
                return(null);
            }

            if (IPEndPointParser.TryParse(Host, out var endpoint))
            {
                return(endpoint);
            }

            return(null);
        }
예제 #10
0
        public void TestValid()
        {
            IPEndPoint ep;

            ep = new IPEndPoint(IPAddress.Loopback, 0);
            Assert.Equal(ep, IPEndPointParser.Parse(ep.ToString()));
            ep = new IPEndPoint(IPAddress.IPv6Loopback, 1234);
            Assert.Equal(ep, IPEndPointParser.Parse(ep.ToString()));
            ep = new IPEndPoint(IPAddress.Parse("10.11.12.13"), 1234);
            Assert.Equal(ep, IPEndPointParser.Parse(ep.ToString()));
            ep = new IPEndPoint(IPAddress.Parse("2001:db8:85a3:0:0:8a2e:370:7334"), 0);
            Assert.Equal(ep, IPEndPointParser.Parse(ep.ToString()));
            ep = new IPEndPoint(IPAddress.Parse("2001::7334"), 1234);
            Assert.Equal(ep, IPEndPointParser.Parse(ep.ToString()));
        }
예제 #11
0
        public static async UniTask <bool> JoinRoomAsync(string roomid, bool isconnect = true, bool beforedisconnect = true)
        {
            var req = new JoinRoomRequest
            {
                peerid    = UniP2PManager.MyPeerID,
                roomid    = roomid,
                ip        = IPEndPointParser.ToString(UniP2PManager.GetEnableIPEndPoint()),
                localport = UniP2PManager.PrivateIPEndPoint.Port
            };

            req.SetHash();
            var result = await HttpClient.Post(GetURIGamekey(UniP2PManager.MatchingSettings.MatchingServerURI) + "/rooms/join", JsonUtility.ToJson(req));

            if (result.StatusCode == 200)
            {
                var room = JsonUtility.FromJson <JoinRoomResponse>(result.Text);
                CurrentRoomID = roomid;
                CurrentToken  = room.token;
                if (isconnect)
                {
                    if (beforedisconnect)
                    {
                        await UniP2PManager.DisConnectAllPeerAsync();
                    }
                    foreach (var peer in room.peers)
                    {
                        if (peer.id == UniP2PManager.MyPeerID)
                        {
                            continue;
                        }
                        await UniP2PManager.SendEmptyPacketAsync(IPEndPointParser.Parse(peer.ip));

                        await UniTask.Delay(100);

                        await UniP2PManager.ConnectPeerAsync(IPEndPointParser.Parse(peer.ip), peer.id, (int)peer.localport);
                    }
                }

                return(true);
            }
            else
            {
                Debug.Debugger.Warning("[SimpleMatchingClient] JoinRoomAsync StatusCode:" + result.StatusCode + ":" + JsonUtility.ToJson(req));
                return(false);
            }
        }
예제 #12
0
        public static async UniTask <bool> JoinRandomRoomAsync(bool isconnect = true, bool beforedisconnect = true)
        {
            var req = new JoinRandomRoomRequest
            {
                peerid = UniP2PManager.MyPeerID,
                ip     = IPEndPointParser.ToString(UniP2PManager.GetEnableIPEndPoint())
            };

            req.SetHash();
            var result = await HttpClient.Post(GetURIGamekey(UniP2PManager.MatchingSettings.MatchingServerURI) + "/rooms/joinrandom", JsonUtility.ToJson(req));

            if (result.StatusCode == 200)
            {
                var room = JsonUtility.FromJson <JoinRandomRoomResponse>(result.Text);
                CurrentRoomID = room.roomid;
                CurrentToken  = room.token;
                if (isconnect)
                {
                    if (beforedisconnect)
                    {
                        await UniP2PManager.DisConnectAllPeerAsync();
                    }

                    List <UniTask <Peer> > tasks = new List <UniTask <Peer> >();
                    foreach (var peer in room.peers)
                    {
                        if (peer.id != UniP2PManager.MyPeerID)
                        {
                            var task = UniP2PManager.ConnectPeerAsync(IPEndPointParser.Parse(peer.ip), peer.id);
                            tasks.Add(task);
                        }
                    }

                    await UniTask.WhenAll(tasks);
                }

                return(true);
            }
            else
            {
                Debug.Debugger.Warning("[SimpleMatchingClient] JoinRandomRoomAsync StatusCode:" + result.StatusCode + ":" + JsonUtility.ToJson(req));
                return(false);
            }
        }
예제 #13
0
        public void Should_TryParse()
        {
            IPEndPoint res;

            IPEndPointParser.TryParse("127.0.0.1", out res).Should().BeTrue();
            res.Should().BeEquivalentTo(new IPEndPoint(new IPAddress(new byte[] { 127, 0, 0, 1 }), 0));

            IPEndPointParser.TryParse("192.168.1.10:80", out res).Should().BeTrue();
            res.Should().BeEquivalentTo(new IPEndPoint(new IPAddress(new byte[] { 192, 168, 1, 10 }), 80));

            var ipV6      = "2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d";
            var ipV6Bytes = new byte[] { 32, 1, 13, 184, 17, 163, 9, 215, 31, 52, 138, 46, 7, 160, 118, 93 };

            IPEndPointParser.TryParse(ipV6, out res).Should().BeTrue();
            res.Should().BeEquivalentTo(new IPEndPoint(new IPAddress(ipV6Bytes), 0));

            IPEndPointParser.TryParse($"[{ipV6}]", out res).Should().BeTrue();
            res.Should().BeEquivalentTo(new IPEndPoint(new IPAddress(ipV6Bytes), 0));

            IPEndPointParser.TryParse($"[{ipV6}]:80", out res).Should().BeTrue();
            res.Should().BeEquivalentTo(new IPEndPoint(new IPAddress(ipV6Bytes), 80));
        }
예제 #14
0
        private void ReadFrameAsync()
        {
            try
            {
                //frame parameters
                int      signalType;
                BinaryID channelName = new BinaryID(new byte[20]);
                int      dataLength;
                byte[]   dataBuffer = new byte[BUFFER_SIZE];

                while (true)
                {
                    #region Read frame from base stream

                    //read frame signal
                    signalType = _baseStream.ReadByte();
                    if (signalType == -1)
                    {
                        return; //End of stream
                    }
                    //read channel name
                    OffsetStream.StreamRead(_baseStream, channelName.ID, 0, 20);

                    //read data length
                    OffsetStream.StreamRead(_baseStream, dataBuffer, 0, 2);
                    dataLength = BitConverter.ToUInt16(dataBuffer, 0);

                    //read data
                    if (dataLength > 0)
                    {
                        OffsetStream.StreamRead(_baseStream, dataBuffer, 0, dataLength);
                    }

                    #endregion

                    switch ((SignalType)signalType)
                    {
                    case SignalType.NOOP:
                        break;

                    case SignalType.ConnectChannelBitChatNetwork:
                        #region ConnectChannelBitChatNetwork

                        lock (_bitChatNetworkChannels)
                        {
                            if (_bitChatNetworkChannels.ContainsKey(channelName))
                            {
                                WriteFrame(SignalType.DisconnectChannelBitChatNetwork, channelName, null, 0, 0);
                            }
                            else
                            {
                                ChannelStream channel = new ChannelStream(this, channelName.Clone(), ChannelType.BitChatNetwork);
                                _bitChatNetworkChannels.Add(channel.ChannelName, channel);

                                BitChatNetworkChannelRequest.BeginInvoke(this, channel.ChannelName, channel, null, null);
                            }
                        }

                        //check if tcp relay is hosted for the channel. reply back tcp relay peers list if available
                        try
                        {
                            List <IPEndPoint> peerEPs = TcpRelayService.GetPeerEPs(channelName, this);

                            if ((peerEPs != null) && (peerEPs.Count > 0))
                            {
                                using (MemoryStream mS = new MemoryStream(128))
                                {
                                    mS.WriteByte(Convert.ToByte(peerEPs.Count));

                                    foreach (IPEndPoint peerEP in peerEPs)
                                    {
                                        IPEndPointParser.WriteTo(peerEP, mS);
                                    }

                                    byte[] data = mS.ToArray();

                                    WriteFrame(SignalType.TcpRelayResponsePeerList, channelName, data, 0, data.Length);
                                }
                            }
                        }
                        catch
                        { }

                        #endregion
                        break;

                    case SignalType.DataChannelBitChatNetwork:
                        #region DataChannelBitChatNetwork

                        try
                        {
                            ChannelStream channel = null;

                            lock (_bitChatNetworkChannels)
                            {
                                channel = _bitChatNetworkChannels[channelName];
                            }

                            channel.WriteBuffer(dataBuffer, 0, dataLength, _channelWriteTimeout);
                        }
                        catch
                        { }

                        #endregion
                        break;

                    case SignalType.DisconnectChannelBitChatNetwork:
                        #region DisconnectChannelBitChatNetwork

                        try
                        {
                            ChannelStream channel;

                            lock (_bitChatNetworkChannels)
                            {
                                channel = _bitChatNetworkChannels[channelName];
                                _bitChatNetworkChannels.Remove(channelName);
                            }

                            channel.SetDisconnected();
                            channel.Dispose();
                        }
                        catch
                        { }

                        #endregion
                        break;

                    case SignalType.ConnectChannelProxyTunnel:
                        #region ConnectChannelProxyTunnel
                    {
                        ChannelStream remoteChannel1 = null;

                        lock (_proxyChannels)
                        {
                            if (_proxyChannels.ContainsKey(channelName))
                            {
                                WriteFrame(SignalType.DisconnectChannelProxy, channelName, null, 0, 0);
                            }
                            else
                            {
                                //add first stream into list
                                remoteChannel1 = new ChannelStream(this, channelName.Clone(), ChannelType.ProxyTunnel);
                                _proxyChannels.Add(remoteChannel1.ChannelName, remoteChannel1);
                            }
                        }

                        if (remoteChannel1 != null)
                        {
                            IPEndPoint tunnelToRemotePeerEP = ConvertChannelNameToEp(channelName);                            //get remote peer ep
                            Connection remotePeerConnection = _connectionManager.GetExistingConnection(tunnelToRemotePeerEP); //get remote channel service

                            if (remotePeerConnection == null)
                            {
                                remoteChannel1.Dispose();
                            }
                            else
                            {
                                try
                                {
                                    //get remote proxy connection channel stream
                                    ChannelStream remoteChannel2 = remotePeerConnection.RequestProxyConnection(_remotePeerEP);

                                    //join current and remote stream
                                    Joint joint = new Joint(remoteChannel1, remoteChannel2);
                                    joint.Disposed += joint_Disposed;

                                    lock (_proxyTunnelJointList)
                                    {
                                        _proxyTunnelJointList.Add(joint);
                                    }

                                    joint.Start();
                                }
                                catch
                                {
                                    remoteChannel1.Dispose();
                                }
                            }
                        }
                    }
                        #endregion
                        break;

                    case SignalType.ConnectChannelProxyConnection:
                        #region ConnectChannelProxyConnection

                        lock (_proxyChannels)
                        {
                            if (_proxyChannels.ContainsKey(channelName))
                            {
                                WriteFrame(SignalType.DisconnectChannelProxy, channelName, null, 0, 0);
                            }
                            else
                            {
                                //add proxy channel stream into list
                                ChannelStream channel = new ChannelStream(this, channelName.Clone(), ChannelType.ProxyTunnel);
                                _proxyChannels.Add(channel.ChannelName, channel);

                                //pass channel as connection async
                                ThreadPool.QueueUserWorkItem(AcceptProxyConnectionAsync, channel);
                            }
                        }

                        #endregion
                        break;

                    case SignalType.DataChannelProxy:
                        #region DataChannelProxy

                        try
                        {
                            ChannelStream channel = null;

                            lock (_proxyChannels)
                            {
                                channel = _proxyChannels[channelName];
                            }

                            channel.WriteBuffer(dataBuffer, 0, dataLength, _channelWriteTimeout);
                        }
                        catch
                        { }

                        #endregion
                        break;

                    case SignalType.DisconnectChannelProxy:
                        #region DisconnectChannelProxy

                        try
                        {
                            ChannelStream channel;

                            lock (_proxyChannels)
                            {
                                channel = _proxyChannels[channelName];
                                _proxyChannels.Remove(channelName);
                            }

                            channel.SetDisconnected();
                            channel.Dispose();
                        }
                        catch
                        { }

                        #endregion
                        break;

                    case SignalType.PeerStatusQuery:
                        #region PeerStatusQuery

                        try
                        {
                            if (_connectionManager.IsPeerConnectionAvailable(ConvertChannelNameToEp(channelName)))
                            {
                                WriteFrame(SignalType.PeerStatusAvailable, channelName, null, 0, 0);
                            }
                        }
                        catch
                        { }

                        #endregion
                        break;

                    case SignalType.PeerStatusAvailable:
                        #region PeerStatusAvailable

                        try
                        {
                            lock (_peerStatusLockList)
                            {
                                object lockObject = _peerStatusLockList[channelName];

                                lock (lockObject)
                                {
                                    Monitor.Pulse(lockObject);
                                }
                            }
                        }
                        catch
                        { }

                        #endregion
                        break;

                    case SignalType.StartTcpRelay:
                        #region StartTcpRelay
                    {
                        BinaryID[] networkIDs;
                        Uri[]      trackerURIs;

                        using (MemoryStream mS = new MemoryStream(dataBuffer, 0, dataLength, false))
                        {
                            //read network id list
                            networkIDs = new BinaryID[mS.ReadByte()];
                            byte[] XORnetworkID = new byte[20];

                            for (int i = 0; i < networkIDs.Length; i++)
                            {
                                mS.Read(XORnetworkID, 0, 20);

                                byte[] networkID = new byte[20];

                                for (int j = 0; j < 20; j++)
                                {
                                    networkID[j] = (byte)(channelName.ID[j] ^ XORnetworkID[j]);
                                }

                                networkIDs[i] = new BinaryID(networkID);
                            }

                            //read tracker uri list
                            trackerURIs = new Uri[mS.ReadByte()];
                            byte[] data = new byte[255];

                            for (int i = 0; i < trackerURIs.Length; i++)
                            {
                                int length = mS.ReadByte();
                                mS.Read(data, 0, length);

                                trackerURIs[i] = new Uri(Encoding.UTF8.GetString(data, 0, length));
                            }
                        }

                        lock (_tcpRelays)
                        {
                            foreach (BinaryID networkID in networkIDs)
                            {
                                if (!_tcpRelays.ContainsKey(networkID))
                                {
                                    TcpRelayService relay = TcpRelayService.StartTcpRelay(networkID, this, _connectionManager.LocalPort, _connectionManager.DhtClient, trackerURIs);
                                    _tcpRelays.Add(networkID, relay);
                                }
                            }
                        }

                        WriteFrame(SignalType.TcpRelayResponseSuccess, channelName, null, 0, 0);
                    }
                        #endregion
                        break;

                    case SignalType.StopTcpRelay:
                        #region StopTcpRelay
                    {
                        BinaryID[] networkIDs;

                        using (MemoryStream mS = new MemoryStream(dataBuffer, 0, dataLength, false))
                        {
                            //read network id list
                            networkIDs = new BinaryID[mS.ReadByte()];
                            byte[] XORnetworkID = new byte[20];

                            for (int i = 0; i < networkIDs.Length; i++)
                            {
                                mS.Read(XORnetworkID, 0, 20);

                                byte[] networkID = new byte[20];

                                for (int j = 0; j < 20; j++)
                                {
                                    networkID[j] = (byte)(channelName.ID[j] ^ XORnetworkID[j]);
                                }

                                networkIDs[i] = new BinaryID(networkID);
                            }
                        }

                        lock (_tcpRelays)
                        {
                            foreach (BinaryID networkID in networkIDs)
                            {
                                if (_tcpRelays.ContainsKey(networkID))
                                {
                                    _tcpRelays[networkID].StopTcpRelay(this);
                                    _tcpRelays.Remove(networkID);
                                }
                            }
                        }

                        WriteFrame(SignalType.TcpRelayResponseSuccess, channelName, null, 0, 0);
                    }
                        #endregion
                        break;

                    case SignalType.TcpRelayResponseSuccess:
                        #region TcpRelayResponseSuccess

                        try
                        {
                            lock (_tcpRelayRequestLockList)
                            {
                                object lockObject = _tcpRelayRequestLockList[channelName];

                                lock (lockObject)
                                {
                                    Monitor.Pulse(lockObject);
                                }
                            }
                        }
                        catch
                        { }

                        #endregion
                        break;

                    case SignalType.TcpRelayResponsePeerList:
                        #region TcpRelayResponsePeerList

                        using (MemoryStream mS = new MemoryStream(dataBuffer, 0, dataLength, false))
                        {
                            int count = mS.ReadByte();
                            List <IPEndPoint> peerEPs = new List <IPEndPoint>(count);

                            for (int i = 0; i < count; i++)
                            {
                                peerEPs.Add(IPEndPointParser.Parse(mS));
                            }

                            TcpRelayPeersAvailable.BeginInvoke(this, channelName.Clone(), peerEPs, null, null);
                        }

                        #endregion
                        break;

                    case SignalType.DhtPacketData:
                        #region DhtPacketData

                        byte[] response = _connectionManager.DhtClient.ProcessPacket(dataBuffer, 0, dataLength, _remotePeerEP.Address);

                        if (response != null)
                        {
                            WriteFrame(SignalType.DhtPacketData, BinaryID.GenerateRandomID160(), response, 0, response.Length);
                        }

                        #endregion
                        break;

                    case SignalType.BitChatNetworkInvitation:
                        #region ChannelInvitationBitChatNetwork

                        if (_connectionManager.Profile.AllowInboundInvitations)
                        {
                            BitChatNetworkInvitation.BeginInvoke(channelName.Clone(), _remotePeerEP, Encoding.UTF8.GetString(dataBuffer, 0, dataLength), null, null);
                        }

                        #endregion
                        break;

                    default:
                        throw new IOException("Invalid frame signal type.");
                    }
                }
            }
            catch
            { }
            finally
            {
                Dispose();
            }
        }
        public virtual Url parse(string url)
        {
            if (string.IsNullOrWhiteSpace(url))
            {
                throw new ArgumentException("Illegal format address string [" + url + "], should not be blank! ");
            }
            Url parsedUrl = tryGet(url);

            if (null != parsedUrl)
            {
                return(parsedUrl);
            }
            IPAddress  ip         = null;
            int        port       = 0;
            Properties properties = null;

            int size = url.Length;
            int pos  = 0;

            //for (int i = 0; i < size; ++i)
            //{
            //    if (RemotingAddressParser_Fields.COLON == url[i])
            //    {
            //        ip = url.Substring(pos, i - pos);
            //        pos = i;
            //        // should not end with COLON
            //        if (i == size - 1)
            //        {
            //            throw new ArgumentException("Illegal format address string [" + url + "], should not end with COLON[:]! ");
            //        }
            //        break;
            //    }
            //    // must have one COLON
            //    if (i == size - 1)
            //    {
            //        throw new ArgumentException("Illegal format address string [" + url + "], must have one COLON[:]! ");
            //    }
            //}

            for (int i = 0; i < size; ++i)
            {
                if (RemotingAddressParser_Fields.QUES == url[i])
                {
                    var ipEndPointString = url.Substring(pos, i - pos);
                    IPEndPointParser.TryParse(ipEndPointString, out var ipEndPoint);
                    ip   = ipEndPoint.Address;
                    port = ipEndPoint.Port;
                    pos  = i;
                    if (i == size - 1)
                    {
                        // should not end with QUES
                        throw new ArgumentException("Illegal format address string [" + url + "], should not end with QUES[?]! ");
                    }
                    break;
                }
                // end without a QUES
                if (i == size - 1)
                {
                    var ipEndPointString          = url.Substring(pos, i - pos + 1);
                    var ipOrHostAndPortSplitIndex = ipEndPointString.LastIndexOf(':');

                    var ipOrHost   = ipEndPointString.Substring(0, ipOrHostAndPortSplitIndex);
                    var portString = ipEndPointString.Substring(ipOrHostAndPortSplitIndex + 1);
                    if (int.TryParse(portString, out var portParsed))
                    {
                        port = portParsed;
                    }
                    else
                    {
                        throw new ArgumentException("Illegal format address string [" + url + "], must have a valid port! ");
                    }

                    if (port <= 0)
                    {
                        throw new ArgumentException("Illegal format address string [" + url + "], must have a valid port! ");
                    }

                    if (IPAddress.TryParse(ipOrHost, out var ipAddress))
                    {
                        ip = ipAddress;
                    }
                    else
                    {
                        var addresses = Dns.GetHostAddresses(ipOrHost);
                        if (addresses.Length == 0)
                        {
                            throw new ArgumentException("Unable to retrieve address from specified host name!");
                        }
                        ip = addresses[0];
                    }

                    pos = size;
                }
            }

            if (pos < (size - 1))
            {
                properties = new Properties();
                while (pos < (size - 1))
                {
                    string key   = null;
                    string value = null;
                    for (int i = pos; i < size; ++i)
                    {
                        if (RemotingAddressParser_Fields.EQUAL == url[i])
                        {
                            key = url.Substring(pos + 1, i - (pos + 1));
                            pos = i;
                            if (i == size - 1)
                            {
                                // should not end with EQUAL
                                throw new ArgumentException("Illegal format address string [" + url + "], should not end with EQUAL[=]! ");
                            }
                            break;
                        }
                        if (i == size - 1)
                        {
                            // must have one EQUAL
                            throw new ArgumentException("Illegal format address string [" + url + "], must have one EQUAL[=]! ");
                        }
                    }
                    for (int i = pos; i < size; ++i)
                    {
                        if (RemotingAddressParser_Fields.AND == url[i])
                        {
                            value = url.Substring(pos + 1, i - (pos + 1));
                            pos   = i;
                            if (i == size - 1)
                            {
                                // should not end with AND
                                throw new ArgumentException("Illegal format address string [" + url + "], should not end with AND[&]! ");
                            }
                            break;
                        }
                        // end without more AND
                        if (i == size - 1)
                        {
                            value = url.Substring(pos + 1, i + 1 - (pos + 1));
                            pos   = size;
                        }
                    }
                    properties.put(key, value);
                }
            }
            parsedUrl = new Url(url, ip, port, properties);
            initUrlArgs(parsedUrl);
            Url.parsedUrls.AddOrUpdate(url, new SoftReference(parsedUrl), (key, oldValue) => new SoftReference(parsedUrl));
            return(parsedUrl);
        }
예제 #16
0
        public void ApplyForwarders(HttpContext context)
        {
            // Gather expected headers. Enabled headers must have the same number of entries.
            string[] forwardedFor = null, forwardedProto = null, forwardedHost = null;
            bool     checkFor = false, checkProto = false, checkHost = false;
            int      entryCount = 0;

            if ((_options.ForwardedHeaders & ForwardedHeaders.XForwardedFor) == ForwardedHeaders.XForwardedFor)
            {
                checkFor     = true;
                forwardedFor = context.Request.Headers.GetCommaSeparatedValues(XForwardedForHeaderName);
                entryCount   = Math.Max(forwardedFor.Length, entryCount);
            }

            if ((_options.ForwardedHeaders & ForwardedHeaders.XForwardedProto) == ForwardedHeaders.XForwardedProto)
            {
                checkProto     = true;
                forwardedProto = context.Request.Headers.GetCommaSeparatedValues(XForwardedProtoHeaderName);
                if (_options.RequireHeaderSymmetry && checkFor && forwardedFor.Length != forwardedProto.Length)
                {
                    _logger.LogDebug(1, "Parameter count mismatch between X-Forwarded-For and X-Forwarded-Proto.");
                    return;
                }
                entryCount = Math.Max(forwardedProto.Length, entryCount);
            }

            if ((_options.ForwardedHeaders & ForwardedHeaders.XForwardedHost) == ForwardedHeaders.XForwardedHost)
            {
                checkHost     = true;
                forwardedHost = context.Request.Headers.GetCommaSeparatedValues(XForwardedHostHeaderName);
                if (_options.RequireHeaderSymmetry &&
                    ((checkFor && forwardedFor.Length != forwardedHost.Length) ||
                     (checkProto && forwardedProto.Length != forwardedHost.Length)))
                {
                    _logger.LogDebug(1, "Parameter count mismatch between X-Forwarded-Host and X-Forwarded-For or X-Forwarded-Proto.");
                    return;
                }
                entryCount = Math.Max(forwardedHost.Length, entryCount);
            }

            // Apply ForwardLimit, if any
            if (_options.ForwardLimit.HasValue && entryCount > _options.ForwardLimit)
            {
                entryCount = _options.ForwardLimit.Value;
            }

            // Group the data together.
            var sets = new SetOfForwarders[entryCount];

            for (int i = 0; i < sets.Length; i++)
            {
                // They get processed in reverse order, right to left.
                var set = new SetOfForwarders();
                if (checkFor && i < forwardedFor.Length)
                {
                    set.IpAndPortText = forwardedFor[forwardedFor.Length - i - 1];
                }
                if (checkProto && i < forwardedProto.Length)
                {
                    set.Scheme = forwardedProto[forwardedProto.Length - i - 1];
                }
                if (checkHost && i < forwardedHost.Length)
                {
                    set.Host = forwardedHost[forwardedHost.Length - i - 1];
                }
                sets[i] = set;
            }

            // Gather initial values
            var connection    = context.Connection;
            var request       = context.Request;
            var currentValues = new SetOfForwarders()
            {
                RemoteIpAndPort = connection.RemoteIpAddress != null ? new IPEndPoint(connection.RemoteIpAddress, connection.RemotePort) : null,
                // Host and Scheme initial values are never inspected, no need to set them here.
            };

            var  checkKnownIps   = _options.KnownNetworks.Count > 0 || _options.KnownProxies.Count > 0;
            bool applyChanges    = false;
            int  entriesConsumed = 0;

            for ( ; entriesConsumed < sets.Length; entriesConsumed++)
            {
                var set = sets[entriesConsumed];
                if (checkFor)
                {
                    // For the first instance, allow remoteIp to be null for servers that don't support it natively.
                    if (currentValues.RemoteIpAndPort != null && checkKnownIps && !CheckKnownAddress(currentValues.RemoteIpAndPort.Address))
                    {
                        // Stop at the first unknown remote IP, but still apply changes processed so far.
                        _logger.LogDebug(1, $"Unknown proxy: {currentValues.RemoteIpAndPort}");
                        break;
                    }

                    IPEndPoint parsedEndPoint;
                    if (IPEndPointParser.TryParse(set.IpAndPortText, out parsedEndPoint))
                    {
                        applyChanges                  = true;
                        set.RemoteIpAndPort           = parsedEndPoint;
                        currentValues.IpAndPortText   = set.IpAndPortText;
                        currentValues.RemoteIpAndPort = set.RemoteIpAndPort;
                    }
                    else if (_options.RequireHeaderSymmetry)
                    {
                        _logger.LogDebug(2, $"Failed to parse forwarded IPAddress: {currentValues.IpAndPortText}");
                        return;
                    }
                }

                if (checkProto)
                {
                    if (!string.IsNullOrEmpty(set.Scheme))
                    {
                        applyChanges         = true;
                        currentValues.Scheme = set.Scheme;
                    }
                    else if (_options.RequireHeaderSymmetry)
                    {
                        _logger.LogDebug(3, $"Failed to parse forwarded scheme: {set.Scheme}");
                        return;
                    }
                }

                if (checkHost)
                {
                    if (!string.IsNullOrEmpty(set.Host))
                    {
                        applyChanges       = true;
                        currentValues.Host = set.Host;
                    }
                    else if (_options.RequireHeaderSymmetry)
                    {
                        _logger.LogDebug(4, $"Failed to parse forwarded host: {set.Host}");
                        return;
                    }
                }
            }

            if (applyChanges)
            {
                if (checkFor && currentValues.RemoteIpAndPort != null)
                {
                    if (connection.RemoteIpAddress != null)
                    {
                        // Save the original
                        request.Headers[XOriginalForName] = new IPEndPoint(connection.RemoteIpAddress, connection.RemotePort).ToString();
                    }
                    if (forwardedFor.Length > entriesConsumed)
                    {
                        // Truncate the consumed header values
                        request.Headers[XForwardedForHeaderName] = forwardedFor.Take(forwardedFor.Length - entriesConsumed).ToArray();
                    }
                    else
                    {
                        // All values were consumed
                        request.Headers.Remove(XForwardedForHeaderName);
                    }
                    connection.RemoteIpAddress = currentValues.RemoteIpAndPort.Address;
                    connection.RemotePort      = currentValues.RemoteIpAndPort.Port;
                }

                if (checkProto && currentValues.Scheme != null)
                {
                    // Save the original
                    request.Headers[XOriginalProtoName] = request.Scheme;
                    if (forwardedProto.Length > entriesConsumed)
                    {
                        // Truncate the consumed header values
                        request.Headers[XForwardedProtoHeaderName] = forwardedProto.Take(forwardedProto.Length - entriesConsumed).ToArray();
                    }
                    else
                    {
                        // All values were consumed
                        request.Headers.Remove(XForwardedProtoHeaderName);
                    }
                    request.Scheme = currentValues.Scheme;
                }

                if (checkHost && currentValues.Host != null)
                {
                    // Save the original
                    request.Headers[XOriginalHostName] = request.Host.ToString();
                    if (forwardedHost.Length > entriesConsumed)
                    {
                        // Truncate the consumed header values
                        request.Headers[XForwardedHostHeaderName] = forwardedHost.Take(forwardedHost.Length - entriesConsumed).ToArray();
                    }
                    else
                    {
                        // All values were consumed
                        request.Headers.Remove(XForwardedHostHeaderName);
                    }
                    request.Host = HostString.FromUriComponent(currentValues.Host);
                }
            }
        }
예제 #17
0
 public void WriteTo(Stream s)
 {
     IPEndPointParser.WriteTo(this, s);
 }
예제 #18
0
 public void WriteTo(Stream s)
 {
     IPEndPointParser.WriteTo(_nodeEP, s);
 }
예제 #19
0
 public NodeContact(Stream s)
 {
     _nodeEP = IPEndPointParser.Parse(s);
     _nodeID = GetNodeID(_nodeEP);
 }
예제 #20
0
        protected override void WritePlainTextTo(Stream s)
        {
            BincodingEncoder encoder = new BincodingEncoder(s, "BP", 7);

            //main settings

            //bitchat local port
            encoder.Encode("local_port", _localPort);

            //check CertificateRevocationList
            encoder.Encode("check_cert_revocation", _checkCertificateRevocationList);

            //upnp enabled
            encoder.Encode("enable_upnp", _enableUPnP);

            //enable invitation
            encoder.Encode("allow_inbound_invitations", _allowInboundInvitations);
            encoder.Encode("allow_only_local_inbound_invitations", _allowOnlyLocalInboundInvitations);

            //download folder
            if (_downloadFolder != null)
            {
                encoder.Encode("download_folder", _downloadFolder);
            }

            //local cert store
            if (_localCertStore != null)
            {
                encoder.Encode("local_cert_store", _localCertStore);
            }

            //profile image
            encoder.Encode("profile_image_date_modified", _profileImageDateModified);

            if (_profileImage != null)
            {
                encoder.Encode("profile_image", _profileImage);
            }

            //tracker urls
            {
                List <Bincoding> trackerList = new List <Bincoding>(_trackerURIs.Length);

                foreach (Uri trackerURI in _trackerURIs)
                {
                    trackerList.Add(Bincoding.GetValue(trackerURI.AbsoluteUri));
                }

                encoder.Encode("tracker_list", trackerList);
            }

            //bitchat info
            {
                List <Bincoding> bitChatInfoList = new List <Bincoding>(_bitChatInfoList.Length);

                foreach (BitChatInfo info in _bitChatInfoList)
                {
                    bitChatInfoList.Add(Bincoding.GetValue(info));
                }

                encoder.Encode("bitchat_info", bitChatInfoList);
            }

            //bootstrap dht nodes
            {
                List <Bincoding> dhtNodeList = new List <Bincoding>(_bootstrapDhtNodes.Length);

                using (MemoryStream mS = new MemoryStream())
                {
                    foreach (IPEndPoint nodeEP in _bootstrapDhtNodes)
                    {
                        mS.SetLength(0);
                        IPEndPointParser.WriteTo(nodeEP, mS);

                        dhtNodeList.Add(Bincoding.GetValue(mS.ToArray()));
                    }
                }

                encoder.Encode("dht_nodes", dhtNodeList);
            }

            //proxy settings

            //proxy type
            if (_proxy != null)
            {
                encoder.Encode("proxy_type", (byte)_proxy.Type);
            }

            //proxy address
            if (_proxyAddress != null)
            {
                encoder.Encode("proxy_address", _proxyAddress);
            }

            //proxy port
            encoder.Encode("proxy_port", _proxyPort);

            //proxy credentials
            if (_proxyCredentials != null)
            {
                encoder.Encode("proxy_user", _proxyCredentials.UserName);
                encoder.Encode("proxy_pass", _proxyCredentials.Password);
            }

            //generic client data
            if ((_clientData != null) && (_clientData.Length > 0))
            {
                encoder.Encode("client_data", _clientData);
            }

            //signal end of settings
            encoder.EncodeNull();
        }
예제 #21
0
        protected override void ReadPlainTextFrom(Stream s)
        {
            BincodingDecoder decoder = new BincodingDecoder(s, "BP");

            if (decoder.Version != 7)
            {
                throw new BitChatException("BitChatProfile data version not supported.");
            }

            NetProxyType proxyType    = NetProxyType.None;
            string       proxyAddress = "127.0.0.1";
            int          proxyPort    = 0;
            string       username     = null;
            string       password     = "";

            while (true)
            {
                Bincoding value = decoder.DecodeNext();

                if (value.Type == BincodingType.NULL)
                {
                    break;
                }

                KeyValuePair <string, Bincoding> item = value.GetKeyValuePair();

                switch (item.Key)
                {
                case "local_port":
                    _localPort = item.Value.GetIntegerValue();
                    break;

                case "check_cert_revocation":
                    _checkCertificateRevocationList = item.Value.GetBooleanValue();
                    break;

                case "enable_upnp":
                    _enableUPnP = item.Value.GetBooleanValue();
                    break;

                case "allow_inbound_invitations":
                    _allowInboundInvitations = item.Value.GetBooleanValue();
                    break;

                case "allow_only_local_inbound_invitations":
                    _allowOnlyLocalInboundInvitations = item.Value.GetBooleanValue();
                    break;

                case "download_folder":
                    _downloadFolder = item.Value.GetStringValue();
                    break;

                case "local_cert_store":
                    _localCertStore = new CertificateStore(item.Value.GetValueStream());
                    break;

                case "profile_image_date_modified":
                    _profileImageDateModified = item.Value.GetLongValue();
                    break;

                case "profile_image":
                case "profile_image_large":
                    _profileImage = item.Value.Value;
                    break;

                case "tracker_list":
                {
                    List <Bincoding> trackerList = item.Value.GetList();

                    _trackerURIs = new Uri[trackerList.Count];
                    int i = 0;

                    foreach (Bincoding trackerItem in trackerList)
                    {
                        _trackerURIs[i++] = new Uri(trackerItem.GetStringValue());
                    }
                }
                break;

                case "bitchat_info":
                {
                    List <Bincoding> bitChatInfoList = item.Value.GetList();

                    _bitChatInfoList = new BitChatInfo[bitChatInfoList.Count];
                    int i = 0;

                    foreach (Bincoding infoItem in bitChatInfoList)
                    {
                        _bitChatInfoList[i++] = new BitChatInfo(infoItem.GetValueStream());
                    }
                }
                break;

                case "dht_nodes":
                {
                    try
                    {
                        List <Bincoding> dhtNodeList = item.Value.GetList();

                        _bootstrapDhtNodes = new IPEndPoint[dhtNodeList.Count];
                        int i = 0;

                        foreach (Bincoding dhtItem in dhtNodeList)
                        {
                            _bootstrapDhtNodes[i++] = IPEndPointParser.Parse(dhtItem.GetValueStream());
                        }
                    }
                    catch (NotSupportedException)
                    {
                        _bootstrapDhtNodes = new IPEndPoint[] { };
                    }
                }
                break;

                case "proxy_type":
                    proxyType = (NetProxyType)item.Value.GetByteValue();
                    break;

                case "proxy_address":
                    proxyAddress = item.Value.GetStringValue();
                    break;

                case "proxy_port":
                    proxyPort = item.Value.GetIntegerValue();
                    break;

                case "proxy_user":
                    username = item.Value.GetStringValue();
                    break;

                case "proxy_pass":
                    password = item.Value.GetStringValue();
                    break;

                case "client_data":
                    if (item.Value.Type == BincodingType.BINARY)
                    {
                        _clientData = item.Value.Value;
                    }

                    break;
                }
            }

            if (string.IsNullOrEmpty(_downloadFolder))
            {
                _downloadFolder = Path.Combine(_profileFolder, "Downloads");

                if (!Directory.Exists(_downloadFolder))
                {
                    try
                    {
                        Directory.CreateDirectory(_downloadFolder);
                    }
                    catch
                    { }
                }
            }

            //apply proxy settings
            NetworkCredential proxyCredentials = null;

            if (username != null)
            {
                proxyCredentials = new NetworkCredential(username, password);
            }

            ConfigureProxy(proxyType, proxyAddress, proxyPort, proxyCredentials);
        }