From 38887ed63360819f0b2d6d4bc909320f4e54179d Mon Sep 17 00:00:00 2001 From: root Date: Mon, 6 May 2024 14:49:02 +0200 Subject: [PATCH] Working on ipv6 --- Makefile | 1 + ftpData.h | 7 +- library/connection.c | 250 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 257 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index cff38a0..86dcdd7 100755 --- a/Makefile +++ b/Makefile @@ -35,6 +35,7 @@ LIBS=-lpthread -lssl -lcrypto ENABLE_IPV6_SUPPORT= +#TO ENABLE IPV6 support uncomment next line ENABLE_IPV6_SUPPORT=-D IPV6_ENABLED ENABLE_PAM_SUPPORT= diff --git a/ftpData.h b/ftpData.h index 92344c2..9cb32c7 100755 --- a/ftpData.h +++ b/ftpData.h @@ -218,8 +218,13 @@ struct clientData workerDataType workerData; socklen_t sockaddr_in_size, sockaddr_in_server_size; + + #ifdef IPV6_ENABLED struct sockaddr_in6 client_sockaddr_in, server_sockaddr_in; - + #else + struct sockaddr_in client_sockaddr_in, server_sockaddr_in; + #endif + int clientPort; char clientIpAddress[INET6_ADDRSTRLEN]; diff --git a/library/connection.c b/library/connection.c index 88a0571..299005e 100755 --- a/library/connection.c +++ b/library/connection.c @@ -344,6 +344,9 @@ int getMaximumSocketFd(int mainSocket, ftpDataType * ftpData) return toReturn; } + +#ifdef IPV6_ENABLED + int createSocket(ftpDataType * ftpData) { //my_printf("\nCreating main socket on port %d", ftpData->ftpParameters.port); @@ -480,6 +483,142 @@ int createPassiveSocket(int port) return sock; } +#else + +int createSocket(ftpDataType * ftpData) +{ + //my_printf("\nCreating main socket on port %d", ftpData->ftpParameters.port); + int sock, errorCode; + struct sockaddr_in temp; + + //Socket creation + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == -1) + { + return -1; + } + temp.sin_family = AF_INET; + temp.sin_addr.s_addr = INADDR_ANY; + temp.sin_port = htons(ftpData->ftpParameters.port); + + //No blocking socket + errorCode = fcntl(sock, F_SETFL, O_NONBLOCK); + + int reuse = 1; + +#ifdef SO_REUSEADDR + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0) + { + perror("setsockopt(SO_REUSEADDR) failed"); + my_printfError("setsockopt(SO_REUSEADDR) failed"); + addLog("socketopt failed", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC); + } + +#endif + +#ifdef SO_REUSEPORT + if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (const char*)&reuse, sizeof(reuse)) < 0) + { + perror("setsockopt(SO_REUSEADDR) failed"); + my_printfError("setsockopt(SO_REUSEADDR) failed"); + addLog("setsocket error", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC); + } +#endif + //Bind socket + errorCode = bind(sock,(struct sockaddr*) &temp,sizeof(temp)); + if (errorCode == -1) + { + if (sock != -1) + { + close(sock); + } + return -1; + } + + //Number of client allowed + errorCode = listen(sock, ftpData->ftpParameters.maxClients + 1); + if (errorCode == -1) + { + if (sock != -1) + { + close(sock); + } + return -1; + } + + return sock; +} + +int createPassiveSocket(int port) +{ + int sock, returnCode; + struct sockaddr_in temp; + + //Socket creation + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == -1) + { + return -1; + } + + temp.sin_family = AF_INET; + temp.sin_addr.s_addr = INADDR_ANY; + temp.sin_port = htons(port); + + int reuse = 1; + +#ifdef SO_REUSEADDR + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0) + { + perror("setsockopt(SO_REUSEADDR) failed"); + my_printfError("setsockopt(SO_REUSEADDR) failed"); + addLog("setsocketerror", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC); + } +#endif + +#ifdef SO_REUSEPORT + if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (const char*)&reuse, sizeof(reuse)) < 0) + { + perror("setsockopt(SO_REUSEADDR) failed"); + my_printfError("setsockopt(SO_REUSEADDR) failed"); + addLog("set socket error", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC); + } +#endif + + //Bind socket + returnCode = bind(sock,(struct sockaddr*) &temp,sizeof(temp)); + + if (returnCode == -1) + { + my_printf("\n Could not bind %d errno = %d", sock, errno); + + if (sock != -1) + { + close(sock); + } + return returnCode; + } + + //Number of client allowed + returnCode = listen(sock, 1); + + if (returnCode == -1) + { + my_printf("\n Could not listen %d errno = %d", sock, errno); + if (sock != -1) + { + close(sock); + } + return returnCode; + } + + return sock; +} + + +#endif + + int createActiveSocket(int port, char *ipAddress) { int sockfd; @@ -720,6 +859,8 @@ int getAvailableClientSocketIndex(ftpDataType * ftpData) return -1; } + +#ifdef IPV6_ENABLED int evaluateClientSocketConnection(ftpDataType * ftpData) { char str[INET6_ADDRSTRLEN]; @@ -858,3 +999,112 @@ int evaluateClientSocketConnection(ftpDataType * ftpData) return 0; } } + +#else + +int evaluateClientSocketConnection(ftpDataType * ftpData) +{ + if (FD_ISSET(ftpData->connectionData.theMainSocket, &ftpData->connectionData.rset)) + { + int availableSocketIndex; + if ((availableSocketIndex = getAvailableClientSocketIndex(ftpData)) != -1) //get available socket + { + if ((ftpData->clients[availableSocketIndex].socketDescriptor = accept(ftpData->connectionData.theMainSocket, (struct sockaddr *)&ftpData->clients[availableSocketIndex].client_sockaddr_in, (socklen_t*)&ftpData->clients[availableSocketIndex].sockaddr_in_size))!=-1) + { + int error, numberOfConnectionFromSameIp, i; + numberOfConnectionFromSameIp = 0; + ftpData->connectedClients++; + ftpData->clients[availableSocketIndex].socketIsConnected = 1; + + error = fcntl(ftpData->clients[availableSocketIndex].socketDescriptor, F_SETFL, O_NONBLOCK); + + fdAdd(ftpData, availableSocketIndex); + + error = getsockname(ftpData->clients[availableSocketIndex].socketDescriptor, (struct sockaddr *)&ftpData->clients[availableSocketIndex].server_sockaddr_in, (socklen_t*)&ftpData->clients[availableSocketIndex].sockaddr_in_server_size); + inet_ntop(AF_INET, + &(ftpData->clients[availableSocketIndex].server_sockaddr_in.sin_addr), + ftpData->clients[availableSocketIndex].serverIpAddress, + INET_ADDRSTRLEN); + //my_printf("\n Server IP: %s", ftpData->clients[availableSocketIndex].serverIpAddress); + //my_printf("Server: New client connected with id: %d", availableSocketIndex); + //my_printf("\nServer: Clients connected: %d", ftpData->connectedClients); + sscanf (ftpData->clients[availableSocketIndex].serverIpAddress,"%d.%d.%d.%d", &ftpData->clients[availableSocketIndex].serverIpV4AddressInteger[0], + &ftpData->clients[availableSocketIndex].serverIpV4AddressInteger[1], + &ftpData->clients[availableSocketIndex].serverIpV4AddressInteger[2], + &ftpData->clients[availableSocketIndex].serverIpV4AddressInteger[3]); + + inet_ntop(AF_INET, + &(ftpData->clients[availableSocketIndex].client_sockaddr_in.sin_addr), + ftpData->clients[availableSocketIndex].clientIpAddress, + INET_ADDRSTRLEN); + //my_printf("\n Client IP: %s", ftpData->clients[availableSocketIndex].clientIpAddress); + ftpData->clients[availableSocketIndex].clientPort = (int) ntohs(ftpData->clients[availableSocketIndex].client_sockaddr_in.sin_port); + //my_printf("\nClient port is: %d\n", ftpData->clients[availableSocketIndex].clientPort); + + ftpData->clients[availableSocketIndex].connectionTimeStamp = (int)time(NULL); + ftpData->clients[availableSocketIndex].lastActivityTimeStamp = (int)time(NULL); + + for (i = 0; i ftpParameters.maxClients; i++) + { + if (i == availableSocketIndex) + { + continue; + } + + if (strcmp(ftpData->clients[availableSocketIndex].clientIpAddress, ftpData->clients[i].clientIpAddress) == 0) { + numberOfConnectionFromSameIp++; + } + } + if (ftpData->ftpParameters.maximumConnectionsPerIp > 0 && + numberOfConnectionFromSameIp >= ftpData->ftpParameters.maximumConnectionsPerIp) + { + int theReturnCode = socketPrintf(ftpData, availableSocketIndex, "sss", "530 too many connection from your ip address ", ftpData->clients[availableSocketIndex].clientIpAddress, " \r\n"); + ftpData->clients[availableSocketIndex].closeTheClient = 1; + addLog("Closing the client", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC); + } + else + { + int returnCode = socketPrintf(ftpData, availableSocketIndex, "s", ftpData->welcomeMessage); + if (returnCode <= 0) + { + ftpData->clients[availableSocketIndex].closeTheClient = 1; + addLog("Closing the client", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC); + } + } + + return 1; + } + else + { + //Errors while accepting, socket will be closed + ftpData->clients[availableSocketIndex].closeTheClient = 1; + //addLog("Closing the client", CURRENT_FILE, CURRENT_LINE, CURRENT_FUNC); + //my_printf("\n2 Errno = %d", errno); + return 1; + } + } + else + { + int socketRefuseFd, socketRefuse_in_size; + socketRefuse_in_size = sizeof(struct sockaddr_in); + struct sockaddr_in socketRefuse_sockaddr_in; + if ((socketRefuseFd = accept(ftpData->connectionData.theMainSocket, (struct sockaddr *)&socketRefuse_sockaddr_in, (socklen_t*)&socketRefuse_in_size))!=-1) + { + int theReturnCode = 0; + char *messageToWrite = "10068 Server reached the maximum number of connection, please try later.\r\n"; + write(socketRefuseFd, messageToWrite, strlen(messageToWrite)); + shutdown(socketRefuseFd, SHUT_RDWR); + theReturnCode = close(socketRefuseFd); + } + + return 0; + } + } + else + { + //No new socket + return 0; + } +} + +#endif