HyperDbg/hyperdbg/hprdbgctrl/code/debugger/communication/tcpserver.cpp
2022-01-18 22:38:56 +03:30

308 lines
6.6 KiB
C++

/**
* @file tcpserver.cpp
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief Server functions over TCP
* @details
* @version 0.1
* @date 2020-08-21
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include "..\hprdbgctrl\pch.h"
//
// Disable it because we want to use inet_ntoa
//
#pragma warning(disable : 4996)
/**
* @brief Create server and wait for a client to connect
* @details this function only accepts one client not multiple clients
*
* @param Port
* @param ClientSocketArg
* @param ListenSocketArg
* @return int
*/
int
CommunicationServerCreateServerAndWaitForClient(PCSTR Port,
SOCKET * ClientSocketArg,
SOCKET * ListenSocketArg)
{
WSADATA wsaData;
int iResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo * result = NULL;
struct addrinfo hints;
//
// Initialize Winsock
//
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0)
{
ShowMessages("err, WSAStartup failed (%x)\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
//
// Resolve the server address and port
//
iResult = getaddrinfo(NULL, Port, &hints, &result);
if (iResult != 0)
{
ShowMessages("err, getaddrinfo failed (%x)\n", iResult);
WSACleanup();
return 1;
}
//
// Create a SOCKET for connecting to server
//
ListenSocket =
socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET)
{
ShowMessages("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
//
// Setup the TCP listening socket
//
iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR)
{
ShowMessages("err, bind failed (%x)\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
freeaddrinfo(result);
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR)
{
ShowMessages("err, listen failed (%x)\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
//
// Accept a client socket
//
sockaddr_in name = {0};
int addrlen = sizeof(name);
ClientSocket = accept(ListenSocket, (struct sockaddr *)&name, &addrlen);
if (ClientSocket == INVALID_SOCKET)
{
ShowMessages("err, accept failed (%x)\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
//
// Show that we connected to a client
//
ShowMessages("connected to : %s:%d\n", inet_ntoa(name.sin_addr), ntohs(name.sin_port));
//
// Set the argument
//
*ClientSocketArg = ClientSocket;
*ListenSocketArg = ListenSocket;
return 0;
}
/**
* @brief listen and receive message as the server
*
* @param ClientSocket
* @param recvbuf
* @param recvbuflen
* @return int
*/
int
CommunicationServerReceiveMessage(SOCKET ClientSocket, char * recvbuf, int recvbuflen)
{
int iResult;
//
// Receive until the peer shuts down the connection
//
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
if (iResult > 0)
{
//
// ShowMessages("bytes received: %d\n", iResult);
//
}
else if (iResult == 0)
{
//
// ShowMessages("connection closing...\n");
//
}
else
{
ShowMessages("err, recv failed (%x)\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
return 0;
}
/**
* @brief send message as the server
*
* @param ClientSocket
* @param sendbuf
* @param length
* @return int
*/
int
CommunicationServerSendMessage(SOCKET ClientSocket, const char * sendbuf, int length)
{
int iSendResult;
//
// Echo the buffer back to the sender
//
iSendResult = send(ClientSocket, sendbuf, length, 0);
if (iSendResult == SOCKET_ERROR)
{
/*
ShowMessages("err, send failed (%x)\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
*/
return 1;
}
return 0;
}
/**
* @brief Shutdown and cleanup connection as server
*
* @param ClientSocket
* @param ListenSocket
* @return int
*/
int
CommunicationServerShutdownAndCleanupConnection(SOCKET ClientSocket,
SOCKET ListenSocket)
{
int iResult;
//
// No longer need server socket
//
closesocket(ListenSocket);
//
// shutdown the connection since we're done
//
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR)
{
//
// We comment this line because the connection might be removed;
// thus, we don't need to show error
//
/*
ShowMessages("err, shutdown failed (%x)\n", WSAGetLastError());
*/
closesocket(ClientSocket);
WSACleanup();
return 1;
}
//
// cleanup
//
closesocket(ClientSocket);
WSACleanup();
return 0;
}
//
// int __cdecl main(void) {
//
// SOCKET ClientSocket;
// SOCKET ListenSocket;
//
// char recvbuf[DEFAULT_BUFLEN] = {0};
// char sendbuf[DEFAULT_BUFLEN] = "hello, I love taylor";
//
// //
// // Start server and wait for client
// //
// CommunicationServerCreateServerAndWaitForClient(DEFAULT_PORT,
// &ClientSocket,
// &ListenSocket);
//
// while (true) {
//
// //
// // Receive message
// //
// if (CommunicationServerReceiveMessage(ClientSocket, recvbuf,
// DEFAULT_BUFLEN) != 0) {
// //
// // Failed, break
// //
// break;
// }
//
// ShowMessages("%s\n", recvbuf);
//
// //
// // Send the message
// //
// if (CommunicationServerSendMessage(ClientSocket, sendbuf,
// strlen(sendbuf)) != 0) {
// //
// // Failed, break
// //
// break;
// }
// }
//
// ShowMessages("close conntection\n");
//
// //
// // Close the connection
// //
// CommunicationServerShutdownAndCleanupConnection(ClientSocket,
// ListenSocket);
//
// return 0;
// }
//