// 检查 IP。 // exception: // 可能会抛出异常 // return: // null 许可 IP 被使用 // 其他 禁止 IP 使用。字符串内容为禁止理由 public string CheckIp(string ip) { // exception: // 可能会抛出异常 IpEntry entry = GetIpEntry(ip); if (entry.IsInBlackList() == true) { return("IP [" + ip + "] 在黑名单之中"); } // return: // false 总量超过 max // true 总量没有超过 max if (entry.CheckTotal(_maxTotalConnectRequest, _period) == false) { // TODO: 何时从黑名单中自动清除? entry.SetInBlackList(); return("IP [" + ip + "] 短时间 (" + _period.TotalSeconds.ToString() + "秒) 内连接请求数超过极限 (" + _maxTotalConnectRequest + "),已被加入黑名单"); } long value = entry.IncOnline(); if (MaxClientsPerIp != -1 && value > MaxClientsPerIp) { entry.DecOnline(); return("IP 地址为 '" + ip + "' 的前端数量超过配额 " + MaxClientsPerIp); } return(null); }
// 释放 IpEntry public void FinishIp(string ip) { IpEntry entry = FindIpEntry(ip); if (entry == null) { return; } long value = entry.DecOnline(); if (value == 0) { // 发出清除 0 值条目的请求。不过也许不该清除,因为后面还要判断 Total。可以改为清除 Total 值小于某个阈值的条目 RemoveIpEntry(ip, true); } }
// 增量 IP 统计数字 // 如果 IP 事项总数超过限额,会抛出异常 // parameters: // strIP 前端机器的 IP 地址。还用于辅助判断是否超过 MaxClients。localhost 是不计算在内的 long _incIpCount(string strIP, int nDelta) { // this.MaxClients = 0; // test if (nDelta != 0 && nDelta != 1 && nDelta != -1) { throw new ArgumentException("nDelta 参数值应为 0 -1 1 之一"); } IpEntry entry = GetIpEntry(strIP); long oldOnline = 0; if (nDelta == 1) { oldOnline = entry.IncOnline(); if (oldOnline >= MaxClientsPerIp) { entry.DecOnline(); throw new Exception("IP 地址为 '" + strIP + "' 的前端数量超过配额 " + MaxClientsPerIp); } return(oldOnline); } else if (nDelta == -1) { oldOnline = entry.DecOnline(); if (oldOnline == 1) { // 发出清除 0 值条目的请求。不过也许不该清除,因为后面还要判断 Total。可以改为清除 Total 值小于某个阈值的条目 RemoveIpEntry(strIP); } return(oldOnline); } else { Debug.Assert(nDelta == 0, ""); } return(entry.OnlineCount); #if NO long v = 0; if (this._ipTable.ContainsKey(strIP) == true) { v = (long)this._ipTable[strIP]; } else { if (this.Count > _nMaxCount && v + nDelta != 0) { throw new OutofSessionException("IP 条目数量超过 " + _nMaxCount.ToString()); } // 判断前端机器台数是否超过限制数额 2014/8/23 if (this.MaxClients != -1 && IsLocalhost(strIP) == false && this.GetClientIpAmount() >= this.MaxClients && v + nDelta != 0) { throw new OutofClientsException("前端机器数量已经达到 " + this.GetClientIpAmount().ToString() + " 个 ( 现有IP: " + StringUtil.MakePathList(GetIpList(), ", ") + " 试图申请的IP: " + strIP + ")。请先释放出通道然后重新访问"); } } if (v + nDelta == 0) { this._ipTable.Remove(strIP); // 及时移走计数器为 0 的条目,避免 hashtable 尺寸太大 } else { this._ipTable[strIP] = v + nDelta; } return(v); // 返回增量前的数字 #endif }