public void HandlePayload(IClient client, int opCode, byte[] payload, int length) { var handler = GetHandler(opCode); if (handler == null) { client.Disconnect(); _log.Warn("Client {0} sent an unhandled opcode {1} - disconnected.", client, opCode.ToString("X8", CultureInfo.InvariantCulture)); return; } var permission = handler.Permission; Contract.Assume(permission != null); if (!client.HasPermission(permission)) { client.Disconnect(); _log.Warn("Client {0} sent opcode {1} which requires permission {2} - disconnected.", client, opCode.ToString("X8", CultureInfo.InvariantCulture), permission.Name); return; } // Invoke the packet handler. Exceptions are caught in the client actor's context. var packet = CreatePacket(opCode, payload, length); client.PostAsync(() => handler.Invoke(client, packet)); }
private static void LoadSingleTypeCacheConfig(IEnumerable <XElement> types) { SingleTypeCacheConfig config; foreach (XElement el in types) { try { string name = el.Attribute("name").Value; if (string.IsNullOrEmpty(name)) { LogProxy.Warn(CACHETYPENAMEISNULL); continue; } bool isFix = false; if (el.Attribute("isfix") != null) { bool.TryParse(el.Attribute("isfix").Value.Trim(), out isFix); if (isFix) { config = new SingleTypeCacheConfig(name, true, 0, 0); MyCacheConfig[name] = config; continue; } } int second = 0; if (el.Attribute("second") != null) { int.TryParse(el.Attribute("second").Value.Trim(), out second); if (second < 0) { second = 0; } } int size = 0; if (el.Attribute("size") != null) { int.TryParse(el.Attribute("size").Value.Trim(), out size); if (size < 0) { size = 0; } } config = new SingleTypeCacheConfig(name, false, second, size); MyCacheConfig[name] = config; } catch (Exception ex) { LogProxy.Error(ex, false); } } }
private static void LoadStorageContexts(IEnumerable <XElement> storageContexts) { StorageContext storageContext; bool isFirst = true; foreach (XElement el in storageContexts) { storageContext = BuilderStorageContext(el); if (string.IsNullOrEmpty(storageContext.Name)) { LogProxy.Warn(STORAGECONTEXTNAMEISNULL); continue; } StorageContexts[storageContext.Name] = storageContext; if (isFirst) { DefaultStorageContext = storageContext; isFirst = false; } else if (string.Equals(storageContext.Name, DEFAULTSTORAGECONTEXT, StringComparison.OrdinalIgnoreCase)) { DefaultStorageContext = storageContext; } } }
private static void LoadSynClientConfig(IEnumerable <XElement> excludedTypes, IEnumerable <XElement> synTypes) { SynClientConfig config; foreach (XElement el in excludedTypes) { try { string name = el.Attribute("name").Value; if (string.IsNullOrEmpty(name)) { LogProxy.Warn(SYNCLIENTTYPENAMEISNULL); continue; } if (MySynClientConfig.ContainsKey(name)) { continue; } config = new SynClientConfig(name, true, false); MySynClientConfig[name] = config; } catch (Exception ex) { LogProxy.Error(ex, false); } } foreach (XElement el in synTypes) { try { string name = el.Attribute("name").Value; if (string.IsNullOrEmpty(name)) { LogProxy.Warn(SYNCLIENTTYPENAMEISNULL); continue; } if (MySynClientConfig.ContainsKey(name)) { continue; } bool isLazy = false; if (el.Attribute("islazy") != null) { bool.TryParse(el.Attribute("islazy").Value.Trim(), out isLazy); } config = new SynClientConfig(name, false, isLazy); MySynClientConfig[name] = config; } catch (Exception ex) { LogProxy.Error(ex, false); } } }
private static Dictionary <string, string> LoadStorageContexts(IEnumerable <XElement> storageContextList) { Dictionary <string, string> storageContexts = new Dictionary <string, string>(); string name; foreach (XElement el in storageContextList) { try { name = el.Attribute("name").Value; if (string.IsNullOrEmpty(name)) { LogProxy.Warn(ALIASISNULL); continue; } storageContexts[name] = el.Value; } catch (Exception ex) { LogProxy.Error(ex, false); } } return(storageContexts); }
public static void SaveObject(SRO obj) { if (obj == null) { LogProxy.Warn(OBJECTISNULL); return; } try { using (TransactionScope scope = new TransactionScope()) { SaveSingleObject(obj); scope.Complete(); } } catch (Exception ex) { obj.Reset(); LogProxy.Error(ex, true); } obj.AfterSave(); }
/// <summary> /// Called when a connection is accepted. /// </summary> private void OnAccept(object sender, SocketAsyncEventArgs args) { var sock = args.AcceptSocket; if (!sock.Connected) { return; } // Wrap stuff in a try block, in case the socket is disposed of. try { var accept = true; // Do we accept multiple connections from the same address? if (!AllowMultipleConnections) { lock (_clients) accept = _clients.All(cl => !cl.EndPoint.Equals(sock.RemoteEndPoint.ToIPEndPoint())); } if (!accept) { _log.Warn("Disconnecting client from {0}; already connected.", sock.RemoteEndPoint); sock.Shutdown(SocketShutdown.Both); sock.Disconnect(false); sock.Close(); } else { // Add the client and thus start receiving. var client = new TcpClient(sock, this, _propagator); client.AddPermission(new ConnectedPermission()); AddClient(client); } } catch (Exception ex) { if (ex is SocketException) { ExceptionManager.RegisterException(ex); } if (!(ex is ObjectDisposedException)) { throw; } throw; } // Continue accepting with the event args we were using before. Accept(args); }
public static void SaveObject(SRO[] objs) { if (objs == null || objs.Length == 0) { LogProxy.Warn(OBJECTSISNULL); return; } var objDistincted = objs.Distinct(new SROComparer()); try { using (TransactionScope scope = new TransactionScope()) { foreach (SRO obj in objDistincted) { if (obj == null) { LogProxy.Warn(OBJECTISNULL); continue; } SaveSingleObject(obj); } scope.Complete(); } } catch (Exception ex) { foreach (SRO obj in objDistincted) { if (obj != null) { obj.Reset(); } } LogProxy.Error(ex, true); } foreach (SRO obj in objDistincted) { if (obj != null) { obj.AfterSave(); } } }
private static void LogError(string message, IClient client, bool disconnect) { Contract.Requires(client != null); Contract.Requires(!string.IsNullOrEmpty(message)); // If we have no client, we're running in library mode, and just throw an exception. if (client == null) { throw new ProtocolViolationException("Protocol violation: {0}".Interpolate(message)); } // Otherwise, report an error, as we're serving actual clients. _log.Warn("Protocol violation by client {0}: {1}".Interpolate(client, message)); if (disconnect) { client.Disconnect(); } }
private static void LoadMappings(IEnumerable <XElement> mappings, AssemblyConfig assembly) { Mapping mapping; foreach (XElement el in mappings) { try { mapping = MappingBuilder(el, assembly); if (string.IsNullOrEmpty(mapping.Name)) { LogProxy.Warn(MAPPINGSNAMEISNULL); continue; } Mappings[mapping.Name] = mapping; } catch (Exception ex) { LogProxy.Error(ex, false); } } }
private static void LoadAssemblies(IEnumerable <XElement> assemblies) { AssemblyConfig assembly; foreach (XElement el in assemblies) { try { assembly = AssemblyConfigBuilder(el); if (string.IsNullOrEmpty(assembly.Name)) { LogProxy.Warn(ASSEMBLYNAMEISNULL); continue; } Assemblies[assembly.Name] = assembly; LoadMappings(el.Elements("Type"), assembly); } catch (Exception ex) { LogProxy.Error(ex, false); } } }
public void SaveObject(SRO obj) { if (obj == null) { LogProxy.Warn(OBJECTISNULL); return; } try { if (BeforeSaveMothed != null) { BeforeSaveMothed(new SRO[] { obj }); } } catch (Exception ex) { LogProxy.Error(ex, false); } try { using (TransactionScope scope = new TransactionScope()) { SaveSingleObject(obj); scope.Complete(); } } catch (Exception ex) { obj.Reset(); LogProxy.Error(ex, true); } AddCache(obj); if (!obj.IsNew && obj.SaveMode != SROSaveMode.NoChange && SynClientService != null) { SynClientService.Add(obj); } obj.IsNew = false; if (obj.SaveMode != SROSaveMode.NoChange) { try { obj.AfterSave(); } catch (Exception ex) { LogProxy.Error(ex, false); } try { if (AfterSaveMothed != null) { AfterSaveMothed(new SRO[] { obj }); } } catch (Exception ex) { LogProxy.Error(ex, false); } } }
public void SaveObject(SRO[] objs) { if (objs == null || objs.Length == 0) { LogProxy.Warn(OBJECTSISNULL); return; } try { if (BeforeSaveMothed != null) { BeforeSaveMothed(objs); } } catch (Exception ex) { LogProxy.Error(ex, false); } var objDistincted = objs.Distinct(new SROComparer()); try { using (TransactionScope scope = new TransactionScope()) { foreach (SRO obj in objDistincted) { if (obj == null) { LogProxy.Warn(OBJECTISNULL); continue; } SaveSingleObject(obj); } scope.Complete(); } } catch (Exception ex) { foreach (SRO obj in objDistincted) { if (obj != null) { obj.Reset(); } } LogProxy.Error(ex, true); } bool isChanged = false; foreach (SRO obj in objDistincted) { if (obj != null) { AddCache(obj); if (!obj.IsNew && obj.SaveMode != SROSaveMode.NoChange && SynClientService != null) { SynClientService.Add(obj); } obj.IsNew = false; if (obj.SaveMode != SROSaveMode.NoChange) { isChanged = true; try { obj.AfterSave(); } catch (Exception ex) { LogProxy.Error(ex, false); } } } } if (isChanged) { try { if (AfterSaveMothed != null) { AfterSaveMothed(objs); } } catch (Exception ex) { LogProxy.Error(ex, false); } } }
private void OnReceiveHeader(object sender, SocketAsyncEventArgs args) { args.Completed -= OnReceiveHeader; var error = args.SocketError; if (error != SocketError.Success) { _log.Warn("Client {0} triggered a socket error ({1}) when trying to fetch a header - disconnected.", this, error); Disconnect(); return; } var bytesTransferred = args.BytesTransferred; Contract.Assume(bytesTransferred >= 0); if (bytesTransferred == 0) { _log.Info("Client {0} disconnected gracefully.", this); Disconnect(); return; } var length = _propagator.IncomingHeaderLength; if (bytesTransferred > length) { _log.Warn("Client {0} sent an invalid-length header ({1} bytes, expected {2}) - disconnected.", this, bytesTransferred, length); Disconnect(); return; } _receivePosition += bytesTransferred; Contract.Assume(_receivePosition < _receiveBuffer.Length); if (_receivePosition != length) { // The header was split; continue receiving... args.Completed += OnReceiveHeader; args.SetBuffer(_headerBuffer, _receivePosition, length - _receivePosition); try { if (!_socket.ReceiveAsync(args)) { OnReceiveHeader(this, args); } else { return; // Call back once the rest of the header arrives. } } catch (Exception ex) { args.Completed -= OnReceiveHeader; Disconnect(); if (ex is ObjectDisposedException) { return; } if (ex is SocketException) { ExceptionManager.RegisterException(ex); return; } throw; } } // We have the full header; reset. _receivePosition = 0; // Decrypt if some sort of encryption scheme has been set. if (Crypt != null) { Crypt.Decrypt(_headerBuffer, 0, length); } // Try to extract header information; if anything goes wrong, it's definitely a malicious client. int recvLength; try { var header = _propagator.HandleHeader(this, _headerBuffer); recvLength = header.Length; _receiveOpCode = header.OpCode; } catch (Exception ex) { ExceptionManager.RegisterException(ex); Disconnect(); return; } if (_receiveLength > MaxReceiveBufferSize) { _log.Warn("Client {0} sent an invalid packet length in a header ({1} bytes) - disconnected.", this, _receiveLength); Disconnect(); return; } if (_receiveLength == 0) { // For empty packets, we just return the buffer, but with no actual region. _propagator.HandlePayload(this, _receiveOpCode, _receiveBuffer, 0); Receive(); return; } _receiveLength = recvLength; // If the client is trying to send a packet larger than our receive buffer, reallocate it. if (recvLength > _receiveBuffer.Length) { _receiveBuffer = new byte[recvLength]; } _eventArgs.SetBuffer(_receiveBuffer, 0, recvLength); args.Completed += OnReceivePayload; try { if (!_socket.ReceiveAsync(args)) { OnReceivePayload(this, args); } } catch (Exception ex) { args.Completed -= OnReceivePayload; Disconnect(); if (ex is ObjectDisposedException) { return; } if (ex is SocketException) { ExceptionManager.RegisterException(ex); return; } throw; } Contract.Assume(_receiveLength < _receiveBuffer.Length); Contract.Assume(_headerBuffer.Length == _propagator.IncomingHeaderLength); // Make the static checker shut up. }