예제 #1
0
        public override bool SendTo(ClientId id, IMessage msg)
        {
            var cl = clients[id];

            if (cl.DeferredDisconnect)
            {
                Root.Log(LogLevel.Debug, "Server: attempt to send message to disconnected client");
                return(false);
            }
            using (var rawBuf = new MemoryStream())
            {
                var buf    = rawBuf.AsUnclosable();
                var header = new MsgHeader {
                    Id = msg.Id, Flags = MessageFlags.None
                };
                if (cl.Secure)
                {
                    using (var container = new MessageCryptoContainer())
                    {
                        symCp.Key = cl.SessionKey;
                        // XXX: generate new symCp.IV
                        container.Store(msg, symCp, Protocol);
                        container.Save(buf, Protocol);
                        header.Size   = (int)buf.Length;
                        header.Flags |= MessageFlags.Secure;
                    }
                }
                else
                {
                    msg.Save(buf, Protocol);
                    header.Size = (int)buf.Length;
                }
                try
                {
                    header.Save(cl.NetStream, Protocol);
                    rawBuf.WriteTo(cl.NetStream);
                }
                catch (IOException e)
                {
                    if (NetUtil.CheckConnectionReset(e))
                    {
                        OnClientConnectionReset(cl);
                        return(false);
                    }
                    throw;
                }
                return(true);
            }
        }
예제 #2
0
        private bool ReceiveMessage(MsgHeader hdr, out IMessage msg)
        {
            msg = null;
            // XXX: could be optimized - use one large buffer + unclosable MemoryStream
            var buf = new byte[hdr.Size];

            try
            {
                netStream.Read(buf, 0, buf.Length);
            }
            catch (IOException e)
            {
                if (NetUtil.CheckConnectionReset(e))
                {
                    OnServerConnectionReset();
                    return(false);
                }
                throw;
            }
            using (var ms = new MemoryStream(buf))
            {
                var msWrap = ms.AsUnclosable();
                if ((hdr.Flags & MessageFlags.Secure) == MessageFlags.Secure)
                {
                    using (var container = new MessageCryptoContainer())
                    {
                        container.Load(msWrap, cfg.Protocol);
                        symCp.Key = sessionKey;
                        msg       = container.Extract(hdr.Id, symCp, cfg.Protocol);
                    }
                }
                else
                {
                    msg = MessageFactory.CreateMessage(hdr.Id);
                    try
                    {
                        msg.Load(msWrap, cfg.Protocol);
                    }
                    catch (MessageLoadException e)
                    {
                        Root.Log(LogLevel.Warning, "Client: bad message received from server ({0})", e.Message);
                        Disconnect();
                        return(false);
                    }
                }
            }
            return(true);
        }
예제 #3
0
 // XXX: write generalized version (both for server and client) and move to core
 public override bool Send(IMessage msg)
 {
     if (!Connected)
     {
         Root.Log(LogLevel.Debug, "Client: attempt to send message with no connection");
         return(false);
     }
     using (var rawBuf = new MemoryStream())
     {
         var buf    = rawBuf.AsUnclosable();
         var header = new MsgHeader();
         header.Id    = msg.Id;
         header.Flags = MessageFlags.None;
         if (sessionKey != null)
         {
             using (var container = new MessageCryptoContainer())
             {
                 symCp.Key = sessionKey;
                 // XXX: generate new symCp.IV
                 container.Store(msg, symCp, cfg.Protocol);
                 container.Save(buf, cfg.Protocol);
                 header.Size   = (int)buf.Length;
                 header.Flags |= MessageFlags.Secure;
             }
         }
         else
         {
             msg.Save(buf, cfg.Protocol);
             header.Size = (int)buf.Length;
         }
         try
         {
             header.Save(netStream, cfg.Protocol);
             rawBuf.WriteTo(netStream);
         }
         catch (IOException e)
         {
             if (NetUtil.CheckConnectionReset(e))
             {
                 OnServerConnectionReset();
                 return(false);
             }
             throw;
         }
     }
     return(true);
 }
예제 #4
0
 private bool ReceiveMessageHeader(MsgHeader hdr, SocketClientBase cl)
 {
     try
     { hdr.Load(cl.NetStream, Protocol); }
     catch (MessageLoadException e)
     {
         if (NetUtil.CheckConnectionReset(e))
         {
             OnClientConnectionReset(cl);
         }
         else
         {
             Root.Log(LogLevel.Warning, "Client {0} : bad message header ({1})",
                      GetClientName(cl), e.Message);
             DisconnectClient(cl, DisconnectReason.Unknown, "bad message header");
         }
         return(false);
     }
     return(true);
 }
예제 #5
0
 private bool ReceiveMessageHeader(MsgHeader hdr)
 {
     try
     {
         hdr.Load(netStream, cfg.Protocol);
     }
     catch (MessageLoadException e)
     {
         if (NetUtil.CheckConnectionReset(e))
         {
             OnServerConnectionReset();
         }
         else
         {
             Root.Log(LogLevel.Warning, "Client: bad message header received from server ({0})", e.Message);
             Disconnect();
         }
         return(false);
     }
     return(true);
 }