/** * handles the connection request message. * * @function handle_connect_msg * * @date 2015-02-11 * * @revision none * * @designer EricTsang * * @programmer EricTsang * * @note * * this function handles a connection request message by starting a new process * that will be used to serve the client. * * @signature static void handle_connect_msg(ConnectMsg* connectMsg) * * @param connectMsg pointer to the received ConnectMsg structure */ static void handle_connect_msg(ConnectMsg* connectMsg) { /* create a new process to serve the client */ if(fork() == 0) { int returnValue; /* reset signal handler */ signal(SIGINT, previousSigHandler); /* print connection request */ printf("connectMsg:\n"); printf(" clientPid: %d\n", connectMsg->clientPid); printf(" priority: %d\n", connectMsg->priority); printf(" filePath: %s\n", connectMsg->filePath); /* handle connection request */ returnValue = serve_client( connectMsg->clientPid, connectMsg->priority, connectMsg->filePath); exit(returnValue); } }
void establish_client(int s) { int pid=0,socket; struct sockaddr sa; socklen_t sa_length = sizeof(struct sockaddr); socket = accept(s, &sa, &sa_length); if( socket < 0 ) main_err("establish_client: Unable to accept client connection."); printf("Accepted client on fd %d\n",socket); fflush(stdout); if( will_fork ) pid = fork(); else printf("Server not forking.\n"); fflush(stdout); switch( pid ) { case 0: /* The child process */ close(unix_socket); close(inet_socket); serve_client(socket); break; case -1: main_err("establish_client: Fork failed."); break; default: close(socket); break; } }
void listen_on_socket(int port, parameters_t *pars, char *password) { struct sockaddr_in server_addr; int on = 1, optlen = sizeof(on), sec60 = 60; memset(&server_addr, 0x00, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port); server_addr.sin_addr.s_addr = INADDR_ANY; server_fd = socket(PF_INET, SOCK_STREAM, 0); if (server_fd == -1) error_exit("error creating socket"); if (bind(server_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) == -1) error_exit("bind() failed"); if (listen(server_fd, SOMAXCONN)) error_exit("listen(%d) failed", SOMAXCONN); if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) error_exit("setsockopt(SO_REUSEADDR) failed"); if (setsockopt(server_fd, IPPROTO_TCP, TCP_KEEPIDLE, &sec60, sizeof(sec60)) == -1) error_exit("setsockopt(TCP_KEEPIDLE) failed"); if (setsockopt(server_fd, IPPROTO_TCP, TCP_KEEPINTVL, &sec60, sizeof(sec60)) == -1) error_exit("setsockopt(TCP_KEEPINTVL) failed"); syslog(LOG_PID|LOG_DAEMON, "Listening on %d", port); for(;;) { int client_fd = accept(server_fd, NULL, NULL); if (client_fd == -1) { if (errno == EINTR) continue; sleep(1); continue; } if (setsockopt(client_fd, SOL_SOCKET, SO_KEEPALIVE, &on, optlen) == -1) { if (sockerror(client_fd, "setsockopt(SO_KEEPALIVE)") == -1) { close(client_fd); continue; } } if (verify_password(client_fd, password) == 0) serve_client(client_fd, pars); close(client_fd); } }
int chsock_serv(CHSOCK *chsock) { int stat, sock; int addrlen; for(;;) { /* Note that addrlen is passed as a pointer * so that the accept call can return the * size of the returned address. */ addrlen = sizeof(struct sockaddr_in); /* This call will block until a new * connection arrives. Then, it will * return the address of the connecting * peer, and a new socket descriptor, sock, * for that connection. */ if ( (sock = accept(chsock->ls, &chsock->peeraddr_in, &addrlen)) == -1 ) { fprintf(stderr, "%s: %s: error: accept failed on socket: %s\n", timestamp(), ProgName, strerror(errno)); return -1; } switch ( fork() ) { case -1: /* Can't fork, just exit. */ return -1; case 0: /* Child process comes here. */ fprintf(stderr, "%s: %s: info: new client connection accepted\n", timestamp(), ProgName); stat = serve_client(chsock, sock); close(sock); exit(stat); default: /* Daemon process comes here. */ /* The daemon needs to remember * to close the new accept socket * after forking the child. This * prevents the daemon from running * out of file descriptor space. It * also means that when the server * closes the socket, that it will * allow the socket to be destroyed * since it will be the last close. */ close(sock); } } /* NOT REACHED */ } /* chsock_serv() */
static void *thread_client(void *args) { struct client_args *client = (struct client_args*)args; pthread_cleanup_push(thread_client_cleanup, args); struct client_info info; info.sfd = client->sockfd; info.cid = abs((int)pthread_self()); pthread_exit(serve_client(&info)); pthread_cleanup_pop(0); }
int main(void) { //BEGIN: initialization struct sockaddr_in sin_server, sin_client; int sfd_server, sfd_client, x; short int connection_id = 0; if((x = sfd_server = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) er("socket()", x); memset((char*) &sin_server, 0, sizeof(struct sockaddr_in)); sin_server.sin_family = AF_INET; sin_server.sin_port = htons(PORTSERVER); sin_server.sin_addr.s_addr = htonl(INADDR_ANY); if((x = bind(sfd_server, (struct sockaddr*) &sin_server, size_sockaddr)) < 0) er("bind()", x); if((x = listen(sfd_server, 1)) < 0) er("listen()", x); printf(ID "FTP Server started up @ local:%d. Waiting for client(s)...\n\n", PORTSERVER); //END: initialization while(1) { if((x = sfd_client = accept(sfd_server, (struct sockaddr*) &sin_client, &size_sockaddr)) < 0) er("accept()", x); printf(ID "Communication started with %s:%d\n", inet_ntoa(sin_client.sin_addr), ntohs(sin_client.sin_port)); fflush(stdout); struct client_info* ci = client_info_alloc(sfd_client, connection_id++); serve_client(ci); } close(sfd_server); printf(ID "Done.\n"); fflush(stdout); return 0; }
int main(int argc, const char *argv[]) { int i = 0; int srv_fd = -1; int epoll_fd = -1; struct epoll_event es[MAX_USERS]; struct user_list* ul = create_user_list(); if (init_server(&srv_fd, &epoll_fd) != 0) return 1; for(;;) { i = epoll_wait(epoll_fd, es, MAX_USERS, -1); if (i < 0) { printf("Cannot wait for events\n"); close(epoll_fd); close(srv_fd); return 1; } for (--i; i > -1; --i) { if (es[i].data.fd == srv_fd) { if (accept_client(srv_fd, epoll_fd) < 0) return 1; } else { if (serve_client(epoll_fd, &es[i], ul) < 0) { close(epoll_fd); close(srv_fd); return 1; } } } } return 0; }
/* Handle the connection of a client. */ static void connection_handler(t_session *session) { int result; #ifdef ENABLE_SSL t_ssl_accept_data sad; #endif #ifdef ENABLE_DEBUG session->current_task = "thread started"; #endif #ifdef ENABLE_SSL if (session->binding->use_ssl) { sad.context = &(session->ssl_context); sad.client_fd = &(session->client_socket); sad.private_key = session->binding->private_key; sad.certificate = session->binding->certificate; sad.ca_certificate = session->binding->ca_certificate; sad.ca_crl = session->binding->ca_crl; sad.timeout = session->kept_alive == 0 ? session->binding->time_for_1st_request : session->binding->time_for_request; sad.min_ssl_version = session->config->min_ssl_version; sad.dh_size = session->config->dh_size; #ifdef ENABLE_DEBUG sad.thread_id = session->thread_id; session->current_task = "ssl accept"; #endif switch (ssl_accept(&sad)) { case SSL_HANDSHAKE_NO_MATCH: log_system(session, "No cypher overlap during SSL handshake."); break; case SSL_HANDSHAKE_TIMEOUT: handle_timeout(session); break; case SSL_HANDSHAKE_OKE: session->socket_open = true; break; } } else #endif session->socket_open = true; if (session->socket_open) { #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_count_connection(session); } #endif do { result = serve_client(session); handle_request_result(session, result); #ifdef ENABLE_TOMAHAWK if (session->parsing_oke) { show_request_to_admins(session->method, session->request_uri, session->http_version, &(session->ip_address), session->http_headers, session->return_code, session->bytes_sent); } #endif #ifdef ENABLE_DEBUG session->current_task = "request done"; #endif if (session->socket_open) { /* Flush the output-buffer */ if (send_buffer(session, NULL, 0) == -1) { session->keep_alive = false; } } #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_count_host(session); } #endif reset_session(session); #ifdef ENABLE_DEBUG session->current_task = "session reset"; #endif if ((session->kept_alive > 0) && (session->config->ban_on_flooding > 0)) { if (client_is_flooding(session)) { if (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny) { ban_ip(&(session->ip_address), session->config->ban_on_flooding, session->config->kick_on_ban); log_system(session, "Client banned because of flooding"); session->keep_alive = false; #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_count_ban(session); } #endif } } } } while (session->keep_alive && session->socket_open); #ifdef ENABLE_DEBUG session->current_task = "session done"; #endif destroy_session(session); close_socket(session); } else { close(session->client_socket); } if (session->config->reconnect_delay > 0) { mark_client_for_removal(session, session->config->reconnect_delay); } else { remove_client(session, true); } #ifdef ENABLE_DEBUG /* Show memory usage by thread */ memdbg_print_log(false); #endif /* Client session ends here */ #ifndef ENABLE_THREAD_POOL pthread_exit(NULL); #endif }
int main(void) { int sockfd, client_sockfd; pid_t pid; char filler[16] = {0}; /* * this is the container for socket's address that contains * address family, ip address, port */ struct sockaddr serv_addr, client_addr; unsigned int supplied_len; unsigned int *ip_suppliedlen_op_storedlen; /* * creates a socket of family Internet sockets (AF_INET) and * of type stream. 0 indicates to system to choose appropriate * protocol (eg: TCP) */ sockfd = socket(AF_INET, SOCK_STREAM, 0); /* * Address represented by struct sockaddr: * first 2 bytes: Address Family, * next 2 bytes: port, * next 2 bytes: ipaddr, * next 8 bytes: zeroes */ /* * htons() and htonl() change endianness to * network order which is the standard for network * communication. */ filler[0] = (unsigned short)AF_INET; filler[2] = (unsigned short)htons(port); filler[4] = (unsigned long)htonl(INADDR_ANY); /* copy data in the filler buffer to the socket address */ memcpy(&serv_addr, filler, sizeof(serv_addr)); /* binds a socket to an address */ bind(sockfd, &serv_addr, sizeof(serv_addr)); /* * allows the process to listen on the socket for given * max number of connections */ listen(sockfd, 5); /* * This ptr on input specifies the length of the supplied sockaddr, * and on output specifies the length of the stored address */ supplied_len = sizeof(client_addr); ip_suppliedlen_op_storedlen = &supplied_len; /* * ready to accept multiple clients - * for each client, we will fork and let the parent come back to * the beginning of the loop to wait for further clients * while the child deals with the accepted client. */ while(1) { /* * causes the process to block until a client connects to the server, * returns a new file descriptor to communicate with the connected client */ client_sockfd = accept(sockfd, &client_addr, ip_suppliedlen_op_storedlen); pid = fork(); if(pid > 0) { /* parent */ close(client_sockfd); continue; } if(pid == 0) { /* child */ close(sockfd); serve_client(client_sockfd); break; } } return 0; }
/* Handle the connection of a client. */ static void connection_handler(t_session *session) { int result; #ifdef ENABLE_SSL t_ssl_accept_data sad; #endif #ifdef ENABLE_MONITOR int connections; #ifdef ENABLE_DEBUG session->current_task = "thread started"; #endif connections = ++open_connections; if (session->config->monitor_enabled) { if (connections > session->config->monitor_stats.simultaneous_connections) { session->config->monitor_stats.simultaneous_connections = connections; } } #endif #ifdef ENABLE_SSL if (session->binding->use_ssl) { sad.context = &(session->ssl_context); sad.client_fd = &(session->client_socket); sad.private_key = session->binding->private_key; sad.certificate = session->binding->certificate; sad.ca_certificate = session->binding->ca_certificate; sad.ca_crl = session->binding->ca_crl; sad.timeout = session->kept_alive == 0 ? session->binding->time_for_1st_request : session->binding->time_for_request; sad.min_ssl_version = session->config->min_ssl_version; sad.dh_size = session->config->dh_size; #ifdef ENABLE_DEBUG session->current_task = "ssl accept"; #endif switch (ssl_accept(&sad)) { case -2: handle_timeout(session); break; case 0: session->socket_open = true; break; } } else #endif session->socket_open = true; if (session->socket_open) { do { result = serve_client(session); handle_request_result(session, result); #ifdef ENABLE_DEBUG session->current_task = "request done"; #endif if (session->socket_open) { send_buffer(session, NULL, 0); /* Flush the output-buffer */ } #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_counter_request(session); if (session->host->monitor_requests && (result > 0)) { monitor_request(session); } } #endif reset_session(session); #ifdef ENABLE_DEBUG session->current_task = "session reset"; #endif if ((session->kept_alive > 0) && (session->config->ban_on_flooding > 0)) { if (client_is_flooding(session)) { if (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny) { ban_ip(&(session->ip_address), session->config->ban_on_flooding, session->config->kick_on_ban); log_system(session, "Client banned because of flooding"); session->keep_alive = false; #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_counter_ban(session); } #endif } } } } while (session->keep_alive && session->socket_open); #ifdef ENABLE_DEBUG session->current_task = "session done"; #endif destroy_session(session); close_socket(session); } else { close(session->client_socket); } #ifdef ENABLE_MONITOR open_connections--; #endif if (session->config->reconnect_delay > 0) { mark_client_for_removal(session, session->config->reconnect_delay); } else { remove_client(session, true); } /* Client session ends here */ #ifndef ENABLE_THREAD_POOL pthread_exit(NULL); #endif }
/** * @brief Start the storage server. * * This is the main entry point for the storage server. It reads the * configuration file, starts listening on a port, and proccesses * commands from clients. */ int main(int argc, char *argv[]) { char time_log[25] , name[40], message[80]; // Process command line arguments. // This program expects exactly one argument: the config file name. assert(argc > 0); if (argc < 2) { printf("Usage %s <config_file>\n", argv[0]); exit(EXIT_FAILURE); } char *config_file = argv[1]; // Read the config file. struct config_params params; record_tables.headTable = NULL; //Initializing the record record_tables.numTable = 0; //to make sure. int status = read_config(config_file, ¶ms, &record_tables); params.status_auth = -1; if (status != 0) { free_memory(&record_tables); printf("Error processing config file.\n"); exit(EXIT_FAILURE); } ///This is the function we used for loading the 'census' file. It's used as a second (or more) parameter and is not strictly necessary. if(argc > 2) { int y; for(y = 2 ; y < argc ; y++) { FILE* pfile = fopen( argv[y] , "r"); ///Opens the file Table* tmp; Key* temp; tmp = find_table(argv[y] , &record_tables); if (tmp != NULL){ ///See if the table (name of the file) exists. if (pfile != NULL) { char c = 50; char key[MAX_KEY_LEN] , value[MAX_VALUE_LEN]; while (c != EOF) { fscanf (pfile , "%s %s" , key , value); ///Read values from file. temp = find_key(key , tmp); struct storage_record record; strcpy(record.value , value); if(temp == NULL) add_key(key , record , tmp); ///If the key doesn't exist it creates a new one. else strcpy(temp->record.value , value); ///If the key exists it updates the key. c = fgetc(pfile); } } } } } generate_time_string_log(time_log); sprintf(name , "Server-%s", time_log ); sprintf(message , "Server on %s:%d\n", params.server_host, params.server_port); if (LOGGING == 2) { log_file = fopen( name , "w" ); if (log_file == NULL) printf("SERVER: An error occured genereting the log file\n"); } else if (LOGGING == 1) log_file = stdout; if (LOGGING == 1 || LOGGING == 2) logger(log_file , message); erase_string(message); // Create a socket. int listensock = socket(PF_INET, SOCK_STREAM, 0); if (listensock < 0) { free_memory(&record_tables); printf("Error creating socket.\n"); exit(EXIT_FAILURE); } // Allow listening port to be reused if defunct. int yes = 1; status = setsockopt(listensock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes); if (status != 0) { free_memory(&record_tables); printf("Error configuring socket.\n"); exit(EXIT_FAILURE); } // Bind it to the listening port. struct sockaddr_in listenaddr; memset(&listenaddr, 0, sizeof listenaddr); listenaddr.sin_family = AF_INET; listenaddr.sin_port = htons(params.server_port); inet_pton(AF_INET, params.server_host, &(listenaddr.sin_addr)); // bind to local IP address status = bind(listensock, (struct sockaddr*) &listenaddr, sizeof listenaddr); if (status != 0) { free_memory(&record_tables); printf("Error binding socket.\n"); exit(EXIT_FAILURE); } // Listen for connections. status = listen(listensock, MAX_LISTENQUEUELEN); if (status != 0) { free_memory(&record_tables); printf("Error listening on socket.\n"); exit(EXIT_FAILURE); } // Listen loop. int wait_for_connections = 1; pthread_t tip; while (wait_for_connections) { // Wait for a connection. params.status_auth = -1; ///Every time it starts listening for connections it "de-authenticates" the server. struct sockaddr_in clientaddr; socklen_t clientaddrlen = sizeof clientaddr; int clientsock = accept(listensock, (struct sockaddr*)&clientaddr, &clientaddrlen); if (clientsock < 0) { printf("Error accepting a connection.\n"); free_memory(&record_tables); exit(EXIT_FAILURE); } sprintf(message , "Got a connection from %s:%d.\n", inet_ntoa(clientaddr.sin_addr), clientaddr.sin_port); if (LOGGING == 1 || LOGGING == 2) logger(log_file , message); erase_string(message); ArgThread *argth = (ArgThread*)malloc(sizeof(ArgThread)); argth->clientsock = clientsock; strcpy(argth->parameters_server.username , params.username); strcpy(argth->parameters_server.password , params.password); argth->parameters_server.status_auth = params.status_auth; argth->parameters_server.concurrency = params.concurrency; strcpy(argth->client_addr , inet_ntoa(clientaddr.sin_addr)); argth->client_port = clientaddr.sin_port; // Get commands from client. if(params.concurrency == 0) serve_client((void*) argth); else if(params.concurrency == 1) pthread_create( &tip , NULL , serve_client , (void*) argth); else if(params.concurrency == 2) { serve_client((void*) argth); } else if(params.concurrency == 3) { pid_t child; if((child = fork()) == 0) { close(listensock); serve_client((void *) argth); exit(0); } free(argth); } } // Stop listening for connections. close(listensock); if (LOGGING == 2) fclose(log_file); free_memory(&record_tables); //printf("%.5f - Server\n" , elapsedTime); return EXIT_SUCCESS; }
int main(int argc, const char *argv[]) { if (argc != 2) { printf("Zla liczba argumentow! Podaj tylko jeden!\n"); return -1; } time_t t; srand((unsigned) time(&t)); unsigned short int port = ((rand() % 500) + 8000); printf("%d\n", port); int CNT = atoi(argv[1]); struct sockaddr_in srv_addr; struct epoll_event e, es[CNT]; //e dany event es[] tablica eventow do obslugi epoll-wielu klientow memset(&srv_addr, 0, sizeof(srv_addr)); // memset zeruje nam te strukturki memset(&e, 0, sizeof(e)); srv_fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); if (srv_fd < 0) { printf("Cannot create socket\n"); return 1; } srv_addr.sin_family = AF_INET; srv_addr.sin_addr.s_addr = htonl(INADDR_ANY); srv_addr.sin_port = htons(port); if (bind(srv_fd, (struct sockaddr*) &srv_addr, sizeof(srv_addr)) < 0) { printf("Cannot bind socket\n"); close(srv_fd); return 1; } if (listen(srv_fd, 1) < 0) { printf("Cannot listen\n"); close(srv_fd); return 1; } epoll_fd = epoll_create(2); if (epoll_fd < 0) { printf("Cannot create epoll\n"); close(srv_fd); return 1; } e.events = EPOLLIN; e.data.fd = srv_fd; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, srv_fd, &e) < 0) { printf("Cannot add server socket to epoll\n"); close(epoll_fd); close(srv_fd); return 1; } size_t cap = CNT; user_list* lista = create_ul(cap); int i = 0; for (;;) { i = epoll_wait(epoll_fd, es, CNT, -1); if (i < 0) { printf("Cannot wait for events\n"); close(epoll_fd); close(srv_fd); return 1; } for (--i; i > -1; --i) { if (es[i].data.fd == srv_fd) { //pobiera nam deskryptor i jesli to bedzie deskryptor serwera, to wchodzi w if'a if (accept_new_client() != 0) return 1; //shut down server } else { serve_client(es[i].data.fd, es[i].events, lista); } } } return 0; }