Ignore:
Timestamp:
Jan 22, 2011, 12:57:36 AM (11 years ago)
Author:
schwittmann
Message:

Several ExternalClient improvements:

  • Separated connected and request job events
  • Added basic authentication
  • Lookup DNS again after getting disconnected
  • Fixed some socket exceptions
  • Prevent slow clients from submitting old jobs by using unique job identifiers
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/CrypPlugins/KeySearcher/Server/Server.cs

    r2411 r2417  
    88class CryptoolServer
    99{
     10    #region Properties
     11
    1012    public int Port {get;set;}
    11    
     13
     14    #endregion
     15
     16    #region Events
     17
    1218    public delegate void JobCompletedDelegate(EndPoint ipep, JobResult j);
    1319    public event JobCompletedDelegate OnJobCompleted;
    1420
    15 
    16     public delegate void ClientConnectedDelegate(EndPoint ipep, String identification);
    17     public event ClientConnectedDelegate OnClientConnected;
    18 
    19     public delegate void ClientDisconnectedDelegate(EndPoint ipep);
    20     public event ClientDisconnectedDelegate OnClientDisconnected;
     21    public delegate bool ClientConnectedDelegate(EndPoint ipep, String name, String password);
     22    public ClientConnectedDelegate OnClientAuth;
     23
     24    public delegate void EndPointDelegate(EndPoint ipep);
     25    public event EndPointDelegate OnClientDisconnected;
     26
     27    public event EndPointDelegate OnClientRequestedJob;
     28
     29    public delegate void StringDelegate(String str);
     30    public event StringDelegate OnErrorLog;
     31   
     32    #endregion
     33
     34    #region Variables
    2135
    2236    private Dictionary<EndPoint, TcpClient> connectedClients = new Dictionary<EndPoint, TcpClient>();
    2337    private TcpListener tcpListener;
    2438    private bool running = false;
     39
     40    #endregion
    2541
    2642    ///<summary>
     
    2945    public void Run()
    3046    {
     47        if (OnJobCompleted == null ||
     48            OnClientAuth == null ||
     49            OnClientDisconnected == null ||
     50            OnClientRequestedJob == null ||
     51            OnErrorLog == null)
     52        {
     53            throw new Exception("One of the mandatory events was not bound");
     54        }
     55
    3156        lock (this)
    3257        {
     
    4267            tcpListener = new TcpListener(IPAddress.Any, Port);
    4368            tcpListener.Start();
    44             Console.WriteLine("Listening for client on port " + Port);
    4569            while (running)
    4670            {
    4771                TcpClient client = tcpListener.AcceptTcpClient();
    48                 Console.WriteLine("Got connection from " + client);
    4972                lock (connectedClients)
    5073                {
     
    6083        catch (SocketException e)
    6184        {
    62             if (running)
    63             {
    64                 Console.WriteLine("CryptoolServer: Got SocketException while running");
    65             }
    66         }
    67 
    68 
    69         tcpListener.Stop();
    70         foreach(var client in connectedClients)
    71             client.Value.Close();
     85            if (running && OnErrorLog != null)
     86            {
     87                OnErrorLog("CryptoolServer: Got SocketException while running");
     88            }
     89        }
     90        finally
     91        {
     92            try
     93            {
     94                tcpListener.Stop();
     95            }
     96            catch (Exception)
     97            {
     98            }
     99            lock (connectedClients)
     100            {
     101                foreach (var client in connectedClients)
     102                    client.Value.Close();
     103            }
     104        }
    72105    }
    73106   
     
    77110        lock(connectedClients)
    78111        {
    79             if(!connectedClients.TryGetValue(i, out client))
    80                 throw new ArgumentException("Not connected to "+i);
     112            if (!connectedClients.TryGetValue(i, out client))
     113            {
     114                if (OnErrorLog != null)
     115                    OnErrorLog("Tried to send job to not present external client " + i);
     116                return;
     117            }
    81118        }
    82119
     
    101138        EndPoint ep = client.Client.RemoteEndPoint;
    102139
     140        bool identified = false;
    103141        try
    104142        {
    105143            var wrapped = new PlatformIndependentWrapper(client);
    106             while(true)
    107             {
    108                 switch((ClientOpcodes)wrapped.ReadInt())
     144            while (true)
     145            {
     146                switch ((ClientOpcodes)wrapped.ReadInt())
    109147                {
    110148                    case ClientOpcodes.HELLO:
    111149                        {
    112                             String identification = wrapped.ReadString();
    113                             if(OnClientConnected != null)
    114                                 OnClientConnected(ep, identification);
     150                            String name = wrapped.ReadString();
     151                            String password = wrapped.ReadString();
     152                            if (OnClientAuth == null || !OnClientAuth(ep, name, password))
     153                            {
     154                                wrapped.WriteInt((int)ServerOpcodes.WRONG_PASSWORD);
     155                                return;
     156                            }
     157                            identified = true;
    115158                        }
    116159                        break;
     
    118161                    case ClientOpcodes.JOB_RESULT:
    119162                        {
     163                            if (!identified)
     164                            {
     165                                if (OnErrorLog != null)
     166                                {
     167                                    OnErrorLog("Client '" + ep + "' tried to post result without identification");
     168                                }
     169                                return;
     170                            }
     171
    120172                            var jobGuid = wrapped.ReadString();
    121173                            var resultList = new List<KeyValuePair<float, int>>();
     
    132184                            rs.ResultList = resultList;
    133185
    134                             if(OnJobCompleted != null)
     186                            if (OnJobCompleted != null)
    135187                            {
    136188                                OnJobCompleted(ep, rs);
     189                            }
     190                        }
     191                        break;
     192
     193                    case ClientOpcodes.JOB_REQUEST:
     194                        {
     195                            if (!identified)
     196                            {
     197                                if (OnErrorLog != null)
     198                                {
     199                                    OnErrorLog("Client '" + ep + "' tried to request job without identification");
     200                                }
     201                                return;
     202                            }
     203
     204                            if (OnClientRequestedJob != null)
     205                            {
     206                                OnClientRequestedJob(ep);
    137207                            }
    138208                        }
     
    141211            }
    142212        }
    143         catch(Exception e)
    144         {
    145             Console.WriteLine("Client exited with exception "+e);
    146         }
    147 
    148         lock(connectedClients)
    149         {
    150             connectedClients.Remove(ep);
    151         }
    152 
    153         if(OnClientDisconnected != null)
    154             OnClientDisconnected(ep);
     213        catch (SocketException)
     214        {
     215            // left blank intentionally. Will be thrown on client disconnect.
     216        }
     217        catch (Exception e)
     218        {
     219            if (OnErrorLog != null)
     220            {
     221                OnErrorLog("Client '" + ep + "' caused exception " + e);
     222            }
     223        }
     224        finally
     225        {
     226            // just to be sure..
     227            client.Close();
     228
     229            lock (connectedClients)
     230            {
     231                connectedClients.Remove(ep);
     232            }
     233
     234            if (OnClientDisconnected != null)
     235                OnClientDisconnected(ep);
     236        }
    155237    }
    156238
Note: See TracChangeset for help on using the changeset viewer.