2012-03-14 62 views
1

我有一個偵聽並接受來自客戶端的連接套接字服務器,它的工作原理如下只從IP地址的連接:服務器插座 - 接受白名單

... do some pre-processing (socket, binds, etc) 
//listen to client 
if (listen(sockfd, BACKLOG) == -1) { 
     perror("listen"); 
     exit(1); 
} 

printf("server: waiting for connections...\n"); 

while(1) { // main accept() loop 
    sin_size = sizeof client_addr; 
    new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size); 
    if (new_fd == -1) { 
     perror("accept"); 
     continue; 
    } 
    //do something ..... 
    ..... 
} 

我怎樣才能限制服務器,所以其只接受來自特定IP地址的連接?舉例來說,我可以創建一個包含IP白名單地址接受,按以下格式的文本文件:
202.168.2.5 - 202.168.2.127
92.104.3.1 - 92.104.4.254
//等

所以基本上我想拒絕所有沒有包含在白名單中的IP地址的連接。如果套接字庫API不支持,我想先接受連接,然後立即關閉套接字,如果peeraddress不在白名單中。但是,如何執行此操作,如何檢查特定IP地址是否在我的白名單中指定的範圍內?任何例子,將不勝感激。

+0

你沒有提到操作系統,但是如果你在* nix系統上運行,你可以簡單地使用TCP Wrappers並讓它爲你完成工作。 – 2012-03-14 05:59:51

回答

3

您想致電getpeername從客戶端獲取地址信息。然後檢查他們的IP地址是否在白名單中。如果沒有,請斷開它們。

爲了檢查他們的IP地址是否在給定的範圍內,你需要將地址字節轉換爲一個數字。你可以做到這一點與以下:

unsigned int n = bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3]; 

如果下界的地址範圍的是A,且上限是B,以及客戶端的IP地址爲X,那麼他們白名單if (A <= X && X <= B)

如果每個IP地址範圍都測試錯誤,那麼它們不在白名單中,您應該斷開它們。

+0

他已經擁有'their_addr'中的地址信息。 – EJP 2012-03-14 05:53:40

+0

啊,好吧,有道理。我做了很多if-else來檢查它是否在允許的IP範圍內。做一點改變是一個完美的解決方案。謝謝 !! – 2012-03-14 06:08:54

2

不知道問題在這裏,或者說問題是什麼。客戶的地址將在their_addr,所以只需搜索你的白名單。如果找不到,關閉。您可能希望將their_addr轉換爲與白名單條目相同的格式,或者反之亦然。

+0

我在我的問題的最後一段提到了這個。我的下一個問題是:如何檢查特定IP地址是否在特定範圍內?例如,92.104.3.120在92.104.3.1和92.104.4.254的範圍內。 – 2012-03-14 05:59:14

+0

@all_by_grace如果範圍是您可以屏蔽的所有子網。否則,你將需要組織一個合適的數據結構。這是一個數據結構問題,而不是網絡問題。 – EJP 2012-03-14 06:01:47

+0

@all_by_grace - 使用'inet_pton'將起始和結束IP地址轉換爲網絡字節順序'int';你現在有一個範圍來檢查。 – 2012-03-14 06:04:49

1

僅在Windows上,您可以使用WSAAccept()而不是accept()WSAAccept()有一個參數,您可以將回調函數傳遞給。在接受新連接之前,將使用該連接的地址和QOS值調用回調。回叫可以根據需要返回CF_ACCEPT,CF_DEFERCF_REJECT