static void CheckError(Socket socket, Dictionary <Socket, RConClient> socketToObject)
        {
            string     addr = "<address lost>";
            RConClient rcon = null;

            if (socketToObject.ContainsKey(socket))
            {
                rcon = socketToObject[socket];
                addr = rcon.remoteAddress;
            }

            try
            {
                addr = socket.RemoteEndPoint.ToString();
            }
            catch (Exception) { }

            try
            {
                socket.Receive(errorBuf);
                ProgramLog.Admin.Log("{0}: remote console connection closed", rcon.Id);
            }
            catch (Exception e)
            {
                HandleSocketException(e);
                ProgramLog.Admin.Log("{0}: remote console connection closed", rcon.Id);
            }

            socket.SafeClose();
        }
        static RConClient AcceptClient(Socket client)
        {
            client.NoDelay = false;

            string addr;

            try
            {
                var rep = client.RemoteEndPoint;
                if (rep != null)
                {
                    addr = rep.ToString();
                }
                else
                {
                    ProgramLog.Admin.Log("Accepted socket disconnected");
                    return(null);
                }

                ProgramLog.Admin.Log("New remote console connection from: {0}", addr);

                var rcon = new RConClient(client, addr, Entry.CoreBuild);

                rcon.Greet();

                clients.Add(rcon);

                return(rcon);
            }
            catch (Exception e)
            {
                ProgramLog.Error.Log("Accepted socket exception ({0})", HandleSocketException(e));
                return(null);
            }
        }
        static bool ReadFromClient(RConClient rcon, Socket socket)
        {
            var buf  = rcon.readBuffer;
            int recv = -1;

            try
            {
                recv =
                    socket.Receive(
                        buf,
                        rcon.bytesRead,
                        buf.Length - rcon.bytesRead,
                        0);
            }
            catch (Exception e)
            {
                ProgramLog.Debug.Log("{0}: socket exception ({1})", rcon.Id, HandleSocketException(e));
                return(false);
            }

            if (recv > 0)
            {
                try
                {
                    rcon.bytesRead += recv;
                    return(rcon.ProcessRead());
                }
                catch (Exception e)
                {
                    var msg = HandleSocketException(e, false);
                    if (msg == null)
                    {
                        ProgramLog.Log(e, "Error processing remote console data stream");
                    }
                    else
                    {
                        ProgramLog.Debug.Log("{0}: socket exception ({1})", rcon.Id, msg);
                    }
                }
            }

            return(false);
        }
        static bool ReadFromClient(RConClient rcon, Socket socket)
        {
            var buf = rcon.readBuffer;
            int recv = -1;

            try
            {
                recv =
                    socket.Receive(
                        buf,
                        rcon.bytesRead,
                        buf.Length - rcon.bytesRead,
                        0);
            }
            catch (Exception e)
            {
                ProgramLog.Debug.Log("{0}: socket exception ({1})", rcon.Id, HandleSocketException(e));
                return false;
            }

            if (recv > 0)
            {
                try
                {
                    rcon.bytesRead += recv;
                    return rcon.ProcessRead();
                }
                catch (Exception e)
                {
                    var msg = HandleSocketException(e, false);
                    if (msg == null)
                        ProgramLog.Log(e, "Error processing remote console data stream");
                    else
                        ProgramLog.Debug.Log("{0}: socket exception ({1})", rcon.Id, msg);
                }
            }

            return false;
        }
 static void DisposeClient(RConClient rcon)
 {
     ProgramLog.Admin.Log("{0}: remote console connection closed.", rcon.Id);
     clients.Remove(rcon);
     rcon.Close();
 }
        static RConClient AcceptClient(Socket client)
        {
            client.NoDelay = false;

            string addr;
            try
            {
                var rep = client.RemoteEndPoint;
                if (rep != null)
                    addr = rep.ToString();
                else
                {
                    ProgramLog.Admin.Log("Accepted socket disconnected");
                    return null;
                }

                ProgramLog.Admin.Log("New remote console connection from: {0}", addr);

                var rcon = new RConClient(client, addr, Entry.CoreBuild);

                rcon.Greet();

                clients.Add(rcon);

                return rcon;
            }
            catch (Exception e)
            {
                ProgramLog.Error.Log("Accepted socket exception ({0})", HandleSocketException(e));
                return null;
            }
        }
 public RConSender(RConClient rcon)
     : base()
 {
     Op = true;
     Client = rcon;
 }
 public RConSender(RConClient rcon)
     : base()
 {
     Op     = true;
     Client = rcon;
 }
 static void DisposeClient(RConClient rcon)
 {
     ProgramLog.Admin.Log("{0}: remote console connection closed.", rcon.Id);
     clients.Remove(rcon);
     rcon.Close();
 }
        public static void RConLoop()
        {
            ProgramLog.Admin.Log("Remote console server started on {0}.", Entry.RConBindAddress);

            var socketToObject = new Dictionary <Socket, RConClient>();
            var readList       = new List <Socket>();
            var errorList      = new List <Socket>();
            var clientList     = new List <Socket>();
            var serverSock     = listener.Server;

            try //TODO: need to get this socket closing code in order
            {
                while (!exit)
                {
                    readList.Clear();
                    readList.Add(serverSock);
                    readList.AddRange(clientList);
                    errorList.Clear();
                    errorList.AddRange(clientList);

                    try
                    {
                        Socket.Select(readList, null, errorList, 500000);
                    }
                    catch (SocketException e)
                    {
                        ProgramLog.Log(e, "Remote console server loop select exception");

                        // sigh, so many places to handle errors

                        listener.Pending();

                        var newList = new List <Socket>();
                        foreach (var sock in clientList)
                        {
                            var close = false;
                            try
                            {
                                if (sock.Connected)
                                {
                                    newList.Add(sock);
                                }
                                else
                                {
                                    close = true;
                                }
                            }
                            catch
                            {
                                close = true;
                            }

                            if (close && socketToObject.ContainsKey(sock))
                            {
                                DisposeClient(socketToObject[sock]);
                            }
                        }

                        clientList = newList;
                        continue;
                    }

                    lock (deadClients)
                        while (deadClients.Count > 0)
                        {
                            var rcon = deadClients.Dequeue();
                            errorList.Remove(rcon.socket);
                            clientList.Remove(rcon.socket);
                            readList.Remove(rcon.socket);
                            DisposeClient(rcon);
                        }

                    foreach (var sock in errorList)
                    {
                        CheckError(sock, socketToObject);

                        if (socketToObject.ContainsKey(sock))
                        {
                            DisposeClient(socketToObject[sock]);
                        }

                        clientList.Remove(sock);
                        readList.Remove(sock);
                    }

                    if (exit)
                    {
                        break;
                    }

                    foreach (var sock in readList)
                    {
                        if (sock == serverSock)
                        {
                            // Accept new clients
                            while (listener.Pending())
                            {
                                var client = listener.AcceptSocket();
                                var rcon   = AcceptClient(client);
                                if (rcon != null)
                                {
                                    clientList.Add(client);
                                    socketToObject[client] = rcon;
                                }
                            }
                        }
                        else
                        {
                            // Handle existing clients
                            bool       rem  = false;
                            RConClient rcon = null;
                            try
                            {
                                rcon = socketToObject[sock];
                                rem  = !ReadFromClient(rcon, sock);
                            }
                            catch (Exception e)
                            {
                                HandleSocketException(e);
                                rem = true;
                            }

                            if (rem)
                            {
                                sock.SafeClose();

                                if (rcon != null)
                                {
                                    DisposeClient(rcon);
                                }

                                clientList.Remove(sock);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                ProgramLog.Log(e, "RConLoop terminated with exception");
            }

            try
            {
                listener.Stop();
            }
            catch (SocketException) { }

            ProgramLog.Admin.Log("Remote console server stopped.");
        }