Article 5RMH9 GET requests knock out my server

GET requests knock out my server

by
rootaccess
from LinuxQuestions.org on (#5RMH9)
Hello. I have a simple listener I wrote in C. The clients are all written perfectly to send data. Even a simple python script will send data. I've got my firewall to limit 3 hits per minute for now for testing. But when someone comes by and does a GET / HTTP 1.0 or 1.1 on my server, I get a `recv() failed due to errno = 104` and my server then returns to my command prompt. Why does this happen? All my server does is accept data and then saves that data into a new file so it uses 2 loops. One to listen to incoming connections constantly, and the next inner loop to basically read the data and send to the fd (the file to save to). Is there a way to prevent certain data?

It would be nice to only allow a specific header or string. Maybe on the firewall? I do understand I need to program this to first run as root, then drop privileges but for the time being I am using a high port and starting this as a non-priv user, then using iptables to redirect on the PREROUTING chain so that the external port routes to the high port. Does it have anything to do with that?

Here is my server basically:

Code:#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <signal.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <time.h>

#define BACKLOG 5
#define LENGTH 8192

void error(const char *msg)
{
perror(msg);
exit(1);
}

int main (int argc, char** argv)
{

/* Ensure port is entered as argument */
if (argc != 2) {
fprintf(stderr, "usage: ./server PORT\n");
exit(EXIT_FAILURE);
}

/* Defining Variables */
int sockfd;
int nsockfd;
int num;
int sin_size;
int *new_sock;
struct sockaddr_in addr_local; /* client addr */
struct sockaddr_in addr_remote; /* server addr */
int PORT = strtol(argv[1], NULL, 10); // use argument as port
int k = 0; //used for fr name incrementing
int errnum;

/* Get the Socket file descriptor */
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 )
{
fprintf(stderr, "ERROR: Failed to obtain socket descriptor. (errno = %d)\n", errno);
exit(1);
}
printf("[+] Obtained socket descriptor %d successfully.\n", sockfd);

/* Fill the client socket address struct */
addr_local.sin_family = AF_INET; // Protocol Family
addr_local.sin_port = htons(PORT); // Port number
addr_local.sin_addr.s_addr = INADDR_ANY; // AutoFill local address
// bzero(&(addr_local.sin_zero), 8); // Flush the rest of struct

/* Bind a special Port */
if( bind(sockfd, (struct sockaddr*)&addr_local, sizeof(struct sockaddr)) == -1 )
{
fprintf(stderr, "ERROR: Failed to bind to port. (errno = %d)\n", errno);
exit(1);
}
printf("[+] Binded to tcp port %d sucessfully.\n",PORT);

/* Listen for connections */
if(listen(sockfd,BACKLOG) == -1)
{
fprintf(stderr, "ERROR: Failed to listen on port. (errno = %d)\n", errno);
exit(1);
}
printf ("[+] Listening on %d...\n", PORT);

/* Accept continuous connections / live server */
while(1)
{
sin_size = sizeof(struct sockaddr_in);

FILE *fp;
fp = fopen("server_logs.txt", "a");
if(fp == NULL)
{
printf("Error: can't create log file\n");
exit(EXIT_FAILURE);
}

/* Get new file name for next connection using k for file_%i.txt */
char fr_name[50]; // The filename buffer. / length of the actual filename, not bytes
snprintf(fr_name, sizeof(char) * 50, "file_%i.txt", k);

char *revbuf = malloc(409600); // Receiver buffer
if (revbuf == NULL) {
printf("Error: malloc failed\n");
exit(EXIT_FAILURE);
}

/* New connections */
if((nsockfd = accept(sockfd, (struct sockaddr *)&addr_remote, &sin_size)) < 0)
{
errnum = errno;
printf("Value of errno: %d\n", errno);
fprintf(fp, "Value of errno: %d\n", errno);
printf("%s\n", strerror( errnum ));
fprintf(fp, "%s\n", strerror( errnum ));
}

/* Time and date variables, file pointer, revbuf buffer to store the data from file */
time_t current = time(NULL);
struct tm *ptr;
char date_time[23];
ptr = localtime(&current);
strftime(date_time, sizeof(date_time), "%Y.%m.%d %H:%M:%S", ptr); //date_time now has date and time

printf("File descriptor: %ld\n", nsockfd);
FILE *fr = fopen(fr_name, "w"); // open the new file name because we received a connection

printf("[+] Connection received from %s\n", inet_ntoa(addr_remote.sin_addr));
fprintf(fp, "[+] Connection received from %s\n", inet_ntoa(addr_remote.sin_addr));

if(fr == NULL)
printf("[-] ERROR: Failed to open file %s.\n", fr_name);

int fr_block_sz = 0;
while((fr_block_sz = recv(nsockfd, revbuf, LENGTH, 0)) > 0)
{
int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr);
if(write_sz < fr_block_sz)
error("File write failed on server.\n");
}
if(fr_block_sz < 0)
{
if (errno == EAGAIN)
printf("recv() timed out.\n");
else
{
fprintf(stderr, "recv() failed due to errno = %d\n", errno);
exit(1);
}
}
printf("[+] File %s received at %s\n\n", fr_name, date_time);
fprintf(fp, "[+] File %s received at %s\n\n", fr_name, date_time);
fclose(fr);
free(revbuf);
close(nsockfd);
fclose(fp);
k++;
}
}latest?d=yIl2AUoC8zA latest?i=RwU8UK4d0MA:yhr0ojR-srI:F7zBnMy latest?i=RwU8UK4d0MA:yhr0ojR-srI:V_sGLiP latest?d=qj6IDK7rITs latest?i=RwU8UK4d0MA:yhr0ojR-srI:gIN9vFwRwU8UK4d0MA
External Content
Source RSS or Atom Feed
Feed Location https://feeds.feedburner.com/linuxquestions/latest
Feed Title LinuxQuestions.org
Feed Link https://www.linuxquestions.org/questions/
Reply 0 comments