Ejemplo n.º 1
0
 private void TryApplyPerChannelEncryption(Channel x)
 {
     if (PerChannelEncryption.IsNullOrEmpty() == false)
     {
         NaiveProtocol.ApplyEncryption(x.DataFilter, PerChannelEncryptionKey, PerChannelEncryption);
     }
 }
Ejemplo n.º 2
0
        private async Task <WebSocketServer> HandleWebsocket(HttpConnection p, byte[] realKey, string encType)
        {
            var ws = new WebSocketServer(p);

            ws.AddToManaged(timeout / 2, timeout);
            NaiveProtocol.ApplyEncryption(ws, realKey, encType); // check encryption parameters before http response
            if ((await ws.HandleRequestAsync(false)).IsConnected == false)
            {
                throw new Exception("websocket handshake failed.");
            }
            return(ws);
        }
Ejemplo n.º 3
0
        private async Task <Tuple <IMsgStream, ImuxSession> > GetMsgStream(HttpConnection p, Settings settings, NaiveProtocol.Request req)
        {
            var realKey = settings.realKey;

            const string XumPrefix   = "chs2:";
            bool         isImux      = req.additionalString.StartsWith(XumPrefix);
            ImuxSession  imux        = null;
            string       encryptType = "";

            if (req.extraStrings.Length > 0)
            {
                encryptType = req.extraStrings[0];
            }
            if (!isImux && req.additionalString != "channels")
            {
                Logger.warning($"{p.remoteEP}: protocol not supported");
                return(null);
            }
            IMsgStream msgStream = null;

            if (isImux)
            {
                var arr = NaiveUtils.DeserializeArray(req.additionalString.Substring(XumPrefix.Length));
                var sessionId = arr[0];
                int wsCount = Int32.Parse(arr[1]), wssoCount = 0, httpCount = 0;
                var connId = Int32.Parse(arr[2]);
                if (arr.Count > 3)
                {
                    wssoCount = Int32.Parse(arr[3]);
                    httpCount = Int32.Parse(arr[4]);
                }
                var connCount = wsCount + wssoCount + httpCount;
                int imuxMax   = settings.imux_max;
                if (imuxMax < 0)
                {
                    imuxMax = 16;
                }
                if (connCount > imuxMax)
                {
                    Logger.warning($"{p.remoteEP}: IMUX count requesting ({connCount}) > imux_max ({imuxMax})");
                    return(null);
                }
                IMsgStream wsOrHttp;
                if (connId < connCount - httpCount)
                {
                    wsOrHttp = await HandleWebsocket(p, realKey, encryptType);
                }
                else
                {
                    p.setStatusCode("200 OK");
                    p.setHeader(HttpHeaders.KEY_Transfer_Encoding, HttpHeaders.VALUE_Transfer_Encoding_chunked);
                    await p.EndResponseAsync();

                    var baseStream = MyStream.FromStream(p.SwitchProtocol());
                    var msf        = new HttpChunkedEncodingMsgStream(baseStream);
                    NaiveProtocol.ApplyEncryption(msf, realKey, encryptType);
                    wsOrHttp = msf;
                }
                lock (imuxSessions) {
                    if (imuxSessions.TryGetValue(sessionId, out imux) == false)
                    {
                        imux = new ImuxSession(sessionId, connCount)
                        {
                            WsCount   = wsCount,
                            WssoCount = wssoCount,
                            HttpCount = httpCount
                        };
                        imuxSessions.Add(sessionId, imux);
                        NaiveUtils.SetTimeout(10 * 1000, () => {
                            if (imux.ConnectedCount != imux.Count)
                            {
                                Logger.warning($"IMUX (id={imux.SessionId}, count={imux.ConnectedCount}/{imux.Count}) timed out");
                                imux.WhenEnd.SetResult(null);
                            }
                        });
                    }
                    if (imux.HandleConnection(wsOrHttp, connId))
                    {
                        // all connections are connected to the imux session, return the msg stream.
                        msgStream = imux.MuxStream;
                    }
                }

                if (msgStream == null)
                {
                    // wait for the end of the imux session, prevent it from being disconncected.
                    await imux.WhenEnd.Task;
                    return(null);
                }
            }
            else
            {
                msgStream = await HandleWebsocket(p, realKey, encryptType);
            }
            return(Tuple.Create(msgStream, imux));
        }