2012-03-14 64 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