TCP ポートをリッスンする非常に安全な C/C++ アプリを作成するためのアドバイスを探しています。他の人が自分のマシンに何をしようとしているのかをのぞき見したいのですが、非常に短いプログラムで必要なことを実行できるのであれば、手の込んだハニーポット アプリをインストールしたくありません。私の目標はシンプルで安全であるため、少なくとも次のことを確実に処理したいと考えてい
ます
。接続が多すぎるサーバー、および
3) クライアントが接続を無期限に開いたままにできないようにする必要があります。
私の現在のアプリは小さくて機能的であるため、サードパーティのライブラリはこのプロジェクトには適していないようです。ただし、アプリをさらに簡素化する小さなライブラリは興味深いものです。また、C++ 標準ライブラリがコードの簡素化に役立つことを期待しています。
以下は、私の最初の試みからのいくつかの重要な機能です。このコードは、Windows、OSX、および Linux でコンパイルされます。
アプリをより安全に、またはよりシンプルにするにはどうすればよいですか?
void SafeClose(SOCKET s)
{
if (s == INVALID_SOCKET)
return;
shutdown(s, SHUT_RDWR);
closesocket(s);
}
void ProcessConnection(SOCKET sock, sockaddr_in *sockAddr)
{
time_t time1;
char szTime[TIME_BUF_SIZE];
char readBuf[READ_BUF_SIZE];
time(&time1);
strftime(szTime, TIME_BUF_SIZE-1, "%Y/%m/%d %H:%M:%S", localtime(&time1));
printf("%s - %s\n", szTime, inet_ntoa(sockAddr->sin_addr));
usleep(1000000); // Wait 1 second for client to send something
int actualReadCount = recv(sock, readBuf, READ_BUF_SIZE-1, 0);
if (actualReadCount < 0 || actualReadCount >= READ_BUF_SIZE){
actualReadCount = 0;
strcpy(readBuf, "(Nothing)");
} else {
CleanString(readBuf, actualReadCount); // Replace non-printable characters
readBuf[actualReadCount] = 0;
}
printf("%s\n\n", readBuf);
SafeClose(sock);
}
int main(int argc, char* argv[])
{
int port = 80;
char cmd[CMD_BUF_SIZE] = {0};
sockaddr_in newSockAddr;
sockaddr_in localSockAddr;
if(argc < 2){
printf("Usage: safelisten PORT\n\n");
return error_code;
}
error_code++;
port = atoi(argv[1]);
BuildCleanAsciiMap(); // Used to replace non-printable characters
localSockAddr.sin_family = AF_INET;
localSockAddr.sin_addr.s_addr = INADDR_ANY;
localSockAddr.sin_port = htons(port);
sizeNewSockAddr = sizeof newSockAddr;
CHK( listenSocket = socket(AF_INET, SOCK_STREAM, 0));
CHK( setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)));
CHK( bind(listenSocket, (sockaddr*)&localSockAddr, sizeof localSockAddr));
CHK( listen(listenSocket, BACKLOG));
CHK( SetNonBlocking(listenSocket));
CHK( SetNonBlocking(0)); // Set STDIN to nonblocking for linux
printf ("Listening on port: %d\nEnter q to quit.\n\n", port);
while(strcmp(cmd, "q")) // While the user has not entered q ...
{
newSocket = accept(listenSocket, (sockaddr*)&newSockAddr, &sizeNewSockAddr);
ReadCmd(cmd, CMD_BUF_SIZE);
if(newSocket == INVALID_SOCKET) {
// accept() would have blocked, thus we wait and try again
usleep(10000);
continue;
}
// Set to nonblocking because we don't want the client to dictate how
// long we are connected.
CHK( SetNonBlocking(newSocket));
ProcessConnection(newSocket, &newSockAddr);
}
SafeClose(listenSocket);
return 0;
}