Esempio n. 1
0
        public void CreateSession(string sessionId, IPAddress serverIP)
        {
            lock (sessions)
            {
                RelaySession session;
                if (sessions.TryGetValue(sessionId, out session))
                {
                    relay.KillSession(session);
                    sessions.Remove(sessionId);
                }

                session = new RelaySession(sessionId)
                {
                    ServerIP          = serverIP,
                    ServerReserveTime = DateTime.Now,
                };

                sessions[sessionId] = session;

                if (DebugLog != null)
                {
                    DebugLog.Write(TraceLevel.Info, String.Format("New session created: {0} ({1})", sessionId, serverIP));
                    DebugLog.Write(TraceLevel.Verbose, FormatSessionTable(sessions));
                }
            }
        }
Esempio n. 2
0
        public void ConnectSession(string sessionId, IPAddress clientIP)
        {
            lock (sessions)
            {
                RelaySession session = null;
                if (!sessions.TryGetValue(sessionId, out session))
                {
                    throw new SessionNotFoundException(sessionId);
                }

                if (!session.ServerConnected)
                {
                    throw new RelayConnectException(sessionId, "Server not connected.");
                }

                session.ClientIP          = clientIP;
                session.ClientReserveTime = DateTime.Now;

                if (DebugLog != null)
                {
                    DebugLog.Write(TraceLevel.Info, String.Format("Session connected: {0} ({1})", sessionId, clientIP));
                    DebugLog.Write(TraceLevel.Verbose, FormatSessionTable(sessions));
                }
            }
        }
Esempio n. 3
0
        protected virtual void ProcessIncomingData(RelaySession session, TcpClient recvClient, byte[] buffer, int bytesRead)
        {
            if (DebugLog != null)
            {
                DebugLog.Write(TraceLevel.Verbose, "Received data from: " + recvClient.Client.RemoteEndPoint);
            }

            TcpClient sendClient = null;

            if (recvClient == session.ServerSocket)
            {
                sendClient = session.ClientSocket;
            }
            else if (recvClient == session.ClientSocket)
            {
                sendClient = session.ServerSocket;
            }

            if (sendClient != null)
            {
                SendData(session, recvClient, sendClient, buffer, bytesRead);
            }
            else
            {
                if (DebugLog != null)
                {
                    DebugLog.Write(TraceLevel.Info, "Received data before peer has connected. Data will be stored in backlog and sent once peer connects.");
                }

                session.DataBackLog.Write(buffer, 0, bytesRead);
            }
        }
Esempio n. 4
0
        private void HandleIncomingConnection(IAsyncResult ar)
        {
            TcpClient newClient = tcpListener.EndAcceptTcpClient(ar);

            if (newClient.Connected)
            {
                lock (sessions)
                {
                    IPAddress    remoteIP = ((IPEndPoint)newClient.Client.RemoteEndPoint).Address;
                    RelaySession session  = null;

                    foreach (var s in sessions.Values)
                    {
                        if (s.ServerIP != null && s.ServerIP.Equals(remoteIP) && !s.ServerConnected)
                        {
                            session = s;
                            session.ServerSocket = newClient;

                            if (DebugLog != null)
                            {
                                DebugLog.Write(TraceLevel.Info, String.Format("Server connected: {0}", remoteIP));
                                DebugLog.Write(TraceLevel.Verbose, FormatSessionTable(sessions));
                            }

                            relay.AddClient(session, newClient);
                            break;
                        }

                        if (s.ClientIP != null && s.ClientIP.Equals(remoteIP) && s.ServerConnected && !s.ClientConnected)
                        {
                            session = s;
                            session.ClientSocket = newClient;

                            if (DebugLog != null)
                            {
                                DebugLog.Write(TraceLevel.Info, String.Format("Client connected: {0}", remoteIP));
                                DebugLog.Write(TraceLevel.Verbose, FormatSessionTable(sessions));
                            }

                            // Tell server that a client has connected
                            byte[] buffer = Encoding.UTF8.GetBytes(ClientConnectedMsg);
                            relay.SendData(session, session.ClientSocket, session.ServerSocket, buffer, buffer.Length);
                            break;
                        }
                    }

                    if (session == null)
                    {
                        newClient.Close();
                    }
                }
            }

            tcpListener.BeginAcceptTcpClient(HandleIncomingConnection, null);
        }
Esempio n. 5
0
        protected virtual void HandleIncomingData(IAsyncResult ar)
        {
            var socketSession = ar.AsyncState as object[];

            if (socketSession != null && socketSession.Length >= 3)
            {
                RelaySession session    = socketSession[0] as RelaySession;
                TcpClient    recvClient = socketSession[1] as TcpClient;
                byte[]       buffer     = socketSession[2] as byte[];

                if (buffer != null &&
                    session != null &&
                    recvClient != null &&
                    recvClient.Client != null)
                {
                    try
                    {
                        int bytesRead = recvClient.Client.EndReceive(ar);

                        if (bytesRead == 0)
                        {
                            if (DebugLog != null)
                            {
                                DebugLog.Write(TraceLevel.Info, "Endpoint disconnected: " + recvClient.Client.RemoteEndPoint);
                            }

                            OnTcpClientDisconnected(recvClient, session);
                        }
                        else
                        {
                            ProcessIncomingData(session, recvClient, buffer, bytesRead);
                        }
                    }
                    catch (SocketException)
                    {
                        if (DebugLog != null)
                        {
                            DebugLog.Write(TraceLevel.Info, "Endpoint disconnected: " + recvClient.Client.RemoteEndPoint);
                        }

                        OnTcpClientDisconnected(recvClient, session);
                    }
                    catch (Exception e)
                    {
                        if (DebugLog != null)
                        {
                            DebugLog.Write(TraceLevel.Error, "HandleIncomingData", e);
                        }
                    }
                }
            }
        }
Esempio n. 6
0
        protected virtual void OnTcpClientDisconnected(TcpClient tcpClient, RelaySession session)
        {
            // Socket closed
            try { tcpClient.Close(); }
            catch { }

            if (tcpClient == session.ServerSocket)
            {
                KillSession(session);
            }
            else if (tcpClient == session.ClientSocket)
            {
                session.ClientSocket = null;
            }
        }
Esempio n. 7
0
        public void SendData(RelaySession session, TcpClient recvClient, TcpClient sendClient, byte[] buffer, int byteCount)
        {
            if (buffer.Length != BufferSize)
            {
                Array.Resize(ref buffer, BufferSize);
            }

            var sendArgs = new SocketAsyncEventArgs();

            sendArgs.UserToken  = new object[] { session, recvClient, sendClient, buffer };
            sendArgs.Completed += OnSendComplete;
            sendArgs.SetBuffer(buffer, 0, byteCount);

            if (!sendClient.Client.SendAsync(sendArgs))
            {
                // Completed synchronously
                OnSendComplete(null, sendArgs);
            }
        }
Esempio n. 8
0
        public virtual void KillSession(RelaySession session)
        {
            if (session != null)
            {
                if (session.ServerSocket != null)
                {
                    try { session.ServerSocket.Close(); } catch {}
                    session.ServerSocket = null;
                }

                if (session.ClientSocket != null)
                {
                    try { session.ClientSocket.Close(); } catch {}
                    session.ClientSocket = null;
                }

                sessions.Remove(session.SessionId);
            }
        }
Esempio n. 9
0
        public virtual void AddClient(RelaySession session, TcpClient tcpClient)
        {
            byte[]   buffer        = new byte[BufferSize]; // Match ethernet MTU
            object[] socketSession = new object[] { session, tcpClient, buffer };

            if (session.DataBackLog.Length > 0)
            {
                if (DebugLog != null)
                {
                    DebugLog.Write(TraceLevel.Info, "Sending backlog data to: " + tcpClient.Client.RemoteEndPoint);
                }

                tcpClient.Client.Send(session.DataBackLog.GetBuffer(), 0, Convert.ToInt32(session.DataBackLog.Length), SocketFlags.None);

                session.DataBackLog.SetLength(0);
                session.DataBackLog.Seek(0, SeekOrigin.Begin);
            }

            tcpClient.Client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, HandleIncomingData, socketSession);
        }
        protected override void OnTcpClientDisconnected(System.Net.Sockets.TcpClient tcpClient, RelaySession session)
        {
            if (tcpClient == session.ClientSocket)
            {
                if (DebugLog != null)
                {
                    DebugLog.Write(TraceLevel.Info, "Remote client disconnected. Sending disconnect message to server.");
                }

                // Tell server that the client has disconnected
                byte[] buffer = Encoding.UTF8.GetBytes(SessionManager.ClientDisconnectedMsg);
                SendData(session, null, session.ServerSocket, buffer, buffer.Length);
            }

            base.OnTcpClientDisconnected(tcpClient, session);
        }