/// <summary> /// 添加域名服务信息 /// </summary> /// <param name="domain"></param> /// <param name="server"></param> /// <param name="removeDomains">域名搜索</param> /// <returns></returns> internal DomainSearchData Add(byte[] domain, DomainServer server, out DomainSearchData removeDomains) { byte[][] domains = this.domains; DomainServer[] servers = this.servers; if (domain.Length != 0) { fixed(byte *domainFixed = domain) { byte *domainEnd = domainFixed + domain.Length; int index = searcher.State != null?searcher.Search(domainFixed, domainEnd) : -1; if (index < 0 || servers[index] == null) { int count = index = 0; foreach (DomainServer nextServer in servers) { if (nextServer != null) { ++count; } } byte[][] newDomains = new byte[++count][]; fixed(byte *reverseDomainFixed = (newDomains[0] = new byte[domain.Length])) { for (byte *start = domainFixed, write = reverseDomainFixed + domain.Length; start != domainEnd; *--write = *start++) { ; } } DomainServer[] newServers = new DomainServer[count]; newServers[0] = server; count = 1; foreach (DomainServer nextServer in servers) { if (nextServer != null) { newDomains[count] = domains[index]; newServers[count] = servers[index]; ++count; } ++index; } if (newServers.Length != count) { Array.Resize(ref newDomains, count); Array.Resize(ref newServers, count); } DomainSearchData newSearchData = new DomainSearchData(newDomains, newServers); removeDomains = this; return(newSearchData); } } } removeDomains = null; return(this); }
internal unsafe HttpDomainServer.Server GetServer(byte *domain, int size) { if (LocalDomainServer == null) { if (size > MaxDomainSize || size == 0) { return(null); } DomainServer server = domains.Get(domain, size); return(server != null && server.IsStart ? server.HttpDomainServer : null); } return(LocalDomainServer); }
/// <summary> /// 获取域名服务信息 /// </summary> /// <param name="domain">域名</param> /// <param name="size">域名长度</param> /// <returns>域名服务信息</returns> internal DomainServer Get(byte *domain, int size) { if (searcher.State != null) { if (lastDomainSize == size && lastLock.TryEnter()) { if (lastDomainSize == size && AutoCSer.Memory.Common.SimpleEqualNotNull(lastDomain.Byte, domain, lastDomainSize)) { DomainServer server = lastServer; lastLock.Exit(); return(server); } lastLock.Exit(); } int index = searcher.Search(domain, domain + size); if (index >= 0) { DomainServer server = servers[index]; if (server != null) { if (lastLock.TryEnter()) { if (lastDomain.Byte == null) { lastLock.SleepFlag = 1; try { lastDomain = Unmanaged.GetPointer(Server.MaxDomainSize, false); AutoCSer.Memory.Common.SimpleCopyNotNull(domain, lastDomain.Byte, lastDomainSize = size); lastServer = server; } finally { lastLock.ExitSleepFlag(); } } else { AutoCSer.Memory.Common.SimpleCopyNotNull(domain, lastDomain.Byte, lastDomainSize = size); lastServer = server; lastLock.Exit(); } } return(server); } } } return(null); }
/// <summary> /// 获取域名服务信息 /// </summary> /// <param name="domain">域名</param> /// <param name="size">域名长度</param> /// <returns>域名服务信息</returns> internal DomainServer Get(byte *domain, int size) { if (searcher.State != null) { if (lastDomainSize == size && Monitor.TryEnter(lastLock)) { if (lastDomainSize == size && Memory.SimpleEqualNotNull(lastDomain.Byte, domain, lastDomainSize)) { DomainServer server = lastServer; Monitor.Exit(lastLock); return(server); } Monitor.Exit(lastLock); } int index = searcher.Search(domain, domain + size); if (index >= 0) { DomainServer server = servers[index]; if (server != null) { if (Monitor.TryEnter(lastLock)) { if (lastDomain.Byte == null) { try { lastDomain = Unmanaged.Get(Server.MaxDomainSize, false, false); Memory.SimpleCopyNotNull(domain, lastDomain.Byte, lastDomainSize = size); lastServer = server; } finally { Monitor.Exit(lastLock); } } else { Memory.SimpleCopyNotNull(domain, lastDomain.Byte, lastDomainSize = size); lastServer = server; Monitor.Exit(lastLock); } } return(server); } } } return(null); }
/// <summary> /// 删除域名服务信息 /// </summary> /// <param name="domain"></param> /// <returns></returns> internal DomainServer Remove(byte[] domain) { if (domain.Length != 0) { byte[][] domains = this.domains; DomainServer[] servers = this.servers; if (searcher.State != null) { int index = searcher.Search(domain); if (index >= 0) { DomainServer removeDomainServer = servers[index]; servers[index] = null; return(removeDomainServer); } } } return(null); }
/// <summary> /// 域名状态检测 /// </summary> /// <param name="domain">域名信息</param> /// <param name="domainServer">域名服务</param> /// <returns>域名状态</returns> internal RegisterState CheckDomain(ref Domain domain, DomainServer domainServer) { byte[] domainData = domain.DomainData; if (domain.Host.Host == null) { if (domain.SslHost.Host == null) { if (domainData.length() == 0) { return(RegisterState.DomainError); } int portIndex = AutoCSer.Memory.indexOfNotNull(domainData, (byte)':'); if (portIndex == -1) { domain.Host.Set(domainData.toStringNotNull(), 80); } else if (portIndex == 0) { return(RegisterState.DomainError); } else { if (!int.TryParse(domainData.toStringNotNull(portIndex + 1, domainData.Length - portIndex - 1), out domain.Host.Port)) { return(RegisterState.DomainError); } domain.Host.Host = domainData.toStringNotNull(0, portIndex); } if (!domain.Host.HostToIPAddress()) { return(RegisterState.DomainError); } } else { if (domain.SslHost.Port == 0) { domain.SslHost.Port = 443; } if (domainData.length() == 0) { if (domain.SslHost.Host.Length == 0) { return(RegisterState.HostError); } string host = domain.SslHost.Host; if (domain.SslHost.Port != 443) { host += ":" + domain.SslHost.Port.toString(); } domain.DomainData = domainData = host.getBytes(); server.Log.Add(AutoCSer.Log.LogType.Error, domain.SslHost.Host + " 缺少指定域名"); } else if (domain.SslHost.Port != 443 && AutoCSer.Memory.indexOfNotNull(domainData, (byte)':') == -1) { domain.DomainData = domainData = (domainData.toStringNotNull() + ":" + domain.SslHost.Port.toString()).getBytes(); } if (!domain.SslHost.HostToIPAddress()) { return(RegisterState.HostError); } } } else { if (domain.Host.Port == 0) { domain.Host.Port = 80; } if (domain.SslHost.Host != null && domain.SslHost.Port == 0) { domain.SslHost.Port = 443; } if (domainData.length() == 0) { if (domain.Host.Host.Length == 0) { return(RegisterState.HostError); } string host = domain.Host.Host; if (domain.Host.Port != 80) { host += ":" + domain.Host.Port.toString(); } domain.DomainData = domainData = host.getBytes(); server.Log.Add(AutoCSer.Log.LogType.Error, domain.Host.Host + " 缺少指定域名"); } else if (domain.SslHost.Host == null) { if (domain.Host.Port != 80 && AutoCSer.Memory.indexOfNotNull(domainData, (byte)':') == -1) { domain.DomainData = domainData = (domainData.toStringNotNull() + ":" + domain.Host.Port.toString()).getBytes(); } } else { if (!domain.SslHost.HostToIPAddress()) { return(RegisterState.HostError); } } if (!domain.Host.HostToIPAddress()) { return(RegisterState.HostError); } } if (domainData.Length > MaxDomainSize) { return(RegisterState.DomainError); } domainData.toLowerNotNull(); DomainSearchData removeDomains = null; Monitor.Enter(domainLock); try { domains = domains.Add(domainData, domainServer, out removeDomains); } finally { Monitor.Exit(domainLock); //if (removeDomains != null) removeDomains.Dispose(); } return(removeDomains == null ? RegisterState.DomainExists : RegisterState.Success); }
/// <summary> /// 启动域名服务 /// </summary> /// <param name="register">域名注册信息</param> /// <returns>域名服务启动状态</returns> private RegisterState start(ref Cache register) { if (isDisposed != 0) { return(RegisterState.Disposed); } if (register.Domains.length() == 0) { return(RegisterState.DomainError); } FileInfo assemblyFile = new FileInfo(register.AssemblyFile); if (!System.IO.File.Exists(register.AssemblyFile)) { server.Log.Add(AutoCSer.Log.LogType.Error, "未找到程序集 " + register.AssemblyFile); return(RegisterState.NotFoundAssembly); } RegisterState state = RegisterState.Unknown; DomainServer domainServer = new DomainServer { Register = register, RegisterServer = this }; int domainCount = domainServer.CheckDomain(ref state); if (state == RegisterState.Success) { try { state = RegisterState.StartError; Assembly assembly = null; DirectoryInfo directory = assemblyFile.Directory; KeyValue <Domain, int>[] domainFlags = register.Domains.getArray(value => new KeyValue <Domain, int>(value, 0)); HashString pathKey = register.AssemblyFile; Monitor.Enter(assemblyLock); try { if (!register.IsShareAssembly || !assemblyCache.TryGetValue(pathKey, out assembly)) { string serverPath = Config.WorkPath + ((ulong)AutoCSer.Pub.StartTime.Ticks).toHex() + ((ulong)AutoCSer.Pub.Identity).toHex() + AutoCSer.Extension.DirectoryExtension.Separator; Directory.CreateDirectory(serverPath); foreach (FileInfo file in directory.GetFiles()) { file.CopyTo(serverPath + file.Name); } assembly = Assembly.LoadFrom(serverPath + assemblyFile.Name); if (register.IsShareAssembly) { assemblyCache.Add(pathKey, assembly); } } } finally { Monitor.Exit(assemblyLock); } domainServer.HttpDomainServer = (HttpDomainServer.Server)Activator.CreateInstance(assembly.GetType(register.ServerTypeName)); domainServer.HttpDomainServer.LoadCheckPath = getLoadCheckPath(directory).FullName; if (domainServer.HttpDomainServer.Start(this, register.Domains, domainServer.RemoveFileWatcher)) { if (FileWatcher != null) { FileWatcher.Add(directory.FullName); } domainServer.FileWatcherPath = directory.FullName; if ((state = start(register.Domains)) == RegisterState.Success) { domainServer.DomainCount = register.Domains.Length; domainServer.Domains = domainFlags; domainServer.IsStart = true; if (!isLoadCache) { Monitor.Enter(domainLock); try { Cache[] registers = domains.GetSaveCache(); if (registers != null) { System.IO.File.WriteAllBytes(cacheFileName, AutoCSer.BinarySerialize.Serializer.Serialize(registers)); } } finally { Monitor.Exit(domainLock); } } server.Log.Add(AutoCSer.Log.LogType.Info, @"domain success " + register.Domains.joinString(@" ", domain => domain.DomainData.toStringNotNull() + (domain.Host.Host == null ? null : (" [" + domain.Host.Host + ":" + domain.Host.Port.toString() + "]")) + (domain.SslHost.Host == null ? null : (" [" + domain.SslHost.Host + ":" + domain.SslHost.Port.toString() + "]"))), new System.Diagnostics.StackFrame(), false); return(RegisterState.Success); } } } catch (Exception error) { server.Log.Add(AutoCSer.Log.LogType.Error, error); } } foreach (Domain domain in register.Domains) { if (domainCount-- == 0) { break; } Monitor.Enter(domainLock); domains.Remove(domain.DomainData); Monitor.Exit(domainLock); } domainServer.Dispose(); return(state); }