2013-09-24 25 views
3

這個問題讓我撓了腦袋幾天了。對於某個網絡上的網站(恰好是DDOS遷移提供商),與其他網站相比,安全管理checkConnect調用似乎要花很長時間。Java安全管理器SocketPermission非常緩慢的解決方案,連接

有沒有什麼辦法可以讓這個網絡上的站點通過安全管理器的訪問檢查?有沒有我不知道的配置?我會(更)瘋了嗎?

下面是展示一個測試用例......

package com.test; 

import java.net.Socket; 
import java.util.ArrayList; 
import java.util.List; 

public class SSCCE 
{ 

static class StatCounter 
{ 
    boolean security; 
    String host; 
    long avg; 
    long total; 
    int iterations; 

    StatCounter(String host) 
    { 
     this.host = host; 
    } 

    @Override 
    public String toString() 
    { 
     return host + "\t\titerations (" + iterations + ")\t\tavg (" + avg + ")\t\tsecurity (" + security + ")"; 
    } 

    void inc(long time) 
    { 
     ++iterations; 
     total += time; 
    } 

    void avg() 
    { 
     avg = total/(long)iterations; 
    } 

    void reset() 
    { 
     total = 0; 
     iterations = 0; 
    } 
} 

static String[] hosts = new String[] 
{ 
    "google.com", 
    "youtube.com", 
    "oracle.com", 
    "random.org", 
    "phpbb.com", 
    "staminus.net", 

    // MUCH Higher Latency with site below (only with security manager enabled?) 
    "blacklotus.net" 
}; 

public static void main(String[] argv) throws Throwable 
{ 
    int iterations = Integer.parseInt(argv[0]); 
    List<StatCounter> counters = new ArrayList<StatCounter>(hosts.length); 
    for(String host : hosts) 
    { 
     counters.add(new StatCounter(host)); 
    } 
    System.out.println("Running Without Security"); 
    for(int i = 0; i < iterations; ++i) 
    { 
     for(StatCounter counter : counters) 
     { 
      long then = System.currentTimeMillis(); 
      new Socket(counter.host, 80).close(); 
      counter.inc(System.currentTimeMillis() - then); 
     } 
    } 
    for(StatCounter counter : counters) 
    { 
     counter.avg(); 
     System.out.println(counter); 
     counter.reset(); 
     counter.security = true; 
    } 
    System.setProperty("java.security.policy", "sscce.policy"); 
    System.setSecurityManager(new SecurityManager()); 

    System.out.println("\n\nRunning With Security"); 

    for(int i = 0; i < iterations; ++i) 
    { 
     for(StatCounter counter : counters) 
     { 
      long then = System.currentTimeMillis(); 
      new Socket(counter.host, 80).close(); 
      counter.inc(System.currentTimeMillis() - then); 
     } 
    } 

    for(StatCounter counter : counters) 
    { 
     counter.avg(); 
     System.out.println(counter); 
    } 

} 
} 

政策文件

運行與
grant 
{ 
permission java.net.SocketPermission "google.com:80", "connect"; 
permission java.net.SocketPermission "youtube.com:80", "connect"; 
permission java.net.SocketPermission "oracle.com:80", "connect"; 
permission java.net.SocketPermission "random.org:80", "connect"; 
permission java.net.SocketPermission "phpbb.com:80", "connect"; 
permission java.net.SocketPermission "staminus.net:80", "connect"; 
permission java.net.SocketPermission "blacklotus.net:80", "connect"; 
}; 

的Java com.test.SSCCE

示例輸出

Running Without Security 
google.com  iterations (4)  avg (65)  security (false) 
youtube.com  iterations (4)  avg (61)  security (false) 
oracle.com  iterations (4)  avg (104)  security (false) 
random.org  iterations (4)  avg (101)  security (false) 
phpbb.com  iterations (4)  avg (143)  security (false) 
staminus.net  iterations (4)  avg (137)  security (false) 
blacklotus.net  iterations (4)  avg (137)  security (false) 


Running With Security 
google.com  iterations (4)  avg (261)  security (true) 
youtube.com  iterations (4)  avg (64)  security (true) 
oracle.com  iterations (4)  avg (103)  security (true) 
random.org  iterations (4)  avg (100)  security (true) 
phpbb.com  iterations (4)  avg (882)  security (true) 
staminus.net  iterations (4)  avg (303)  security (true) 
blacklotus.net  iterations (4)  avg (4669)  security (true) 

我真的很感激任何意見,謝謝。

據我所看到的,一切都看起來很不錯(除了什麼似乎是網絡延遲!)

+0

你能拿起你的錯誤日誌嗎?我認爲代碼是正確的 – PengWu

+0

沒有錯誤。連接正在發生,但是使用blacklotus.net時,延遲增加了至少4倍(但僅在安裝了安全管理器的情況下)。如果您願意,請運行該示例並確認我的數據能夠被複制。謝謝 –

回答

3

我通過使用附加的調試信息對JRE系統庫進行逆向工程,最終找出了這種現象的根本原因。我能夠追蹤延遲的原因倒在本地方法

java.net.Inet4AddressImpl.getHostByAddr([B)Ljava.lang.String 

原來從它的IP地址解決問題的主機發生故障,原因未知和超時後,調用方法嘗試另一條路線返回一個有效的主機名。我已經檢查了這與幾個基於Web的反向查找工具,似乎最有可能與blacklotus.net問題(或可能是一個功能,以防止反向查找?)

我希望這可以幫助任何遇到這樣的奇球案。 T-減36小時,案件結案。