int client_handler(int sock) { pid_t pid; pid = fork(); if(pid < 0) { fprintf(stderr, "Fork failed\n"); exit(1); } else if (pid == 0) { request_handler(sock); exit(0); } else { int return_val; waitpid(pid, &return_val, 0); if(WEXITSTATUS(return_val) == 1) return 1; } return 0; }
/* * worker_thread - thread that initialized first, then invoke when * reqeust comming in */ void *worker_thread(void *vargp) { #ifdef DEBUG printf("enter worker_thread\n"); #endif Pthread_detach(pthread_self()); while (1) { int client_fd = sbuf_remove(&sbuf); request_handler(client_fd); } }
void Session::on_execute(uv_async_t* data, int status) { #else void Session::on_execute(uv_async_t* data) { #endif Session* session = static_cast<Session*>(data->data); bool is_closing = false; RequestHandler* temp = NULL; while (session->request_queue_->dequeue(temp)) { RequestHandler::Ptr request_handler(temp); if (request_handler) { request_handler->dec_ref(); // Queue reference request_handler->init(session->config_, session->keyspace(), session->token_map_.get(), session->prepared_metadata_); bool is_done = false; while (!is_done) { request_handler->next_host(); if (!request_handler->current_host()) { request_handler->set_error(CASS_ERROR_LIB_NO_HOSTS_AVAILABLE, "All connections on all I/O threads are busy"); break; } size_t start = session->current_io_worker_; for (size_t i = 0, size = session->io_workers_.size(); i < size; ++i) { const IOWorker::Ptr& io_worker = session->io_workers_[start % size]; if (io_worker->execute(request_handler)) { session->current_io_worker_ = (start + 1) % size; is_done = true; break; } start++; } } } else { is_closing = true; } } if (is_closing) { session->pending_workers_count_ = session->io_workers_.size(); for (IOWorkerVec::iterator it = session->io_workers_.begin(), end = session->io_workers_.end(); it != end; ++it) { (*it)->close_async(); } } }
void* socket_handler(void *arg) { int sock = *((int*)arg); int result = SOCKET_CONTINUE; printf("SOCKET %d CONNECTED\n", sock); while (result == SOCKET_CONTINUE) { result = request_handler(sock); } printf("SOCKET %d CLOSED\n", sock); close(sock); return NULL; }
Future::Ptr Session::execute(const Request::ConstPtr& request, const Address* preferred_address) { ResponseFuture::Ptr future(new ResponseFuture()); RequestHandler::Ptr request_handler(new RequestHandler(request, future, this)); if (preferred_address) { request_handler->set_preferred_address(*preferred_address); } execute(request_handler); return future; }
/** * Reads data from a client socket and passes forward to handle a message or removes a player * and closes socket. * @param[in] client_fd File descriptor of a client that is currently served. * @param base_rdfs Bit array holding file descriptors to be served by the server. * @param players_list Pointer to a list holding players. * @param games_list Pointer to a list holding games. * @param threads_list Pointer to a list holding threads. * @param players_list_mutex Pointer to a mutex guarding players list. * @param games_list_mutex Pointer to a mutex guarding games list. * @param threads_list_mutex Pointer to a mutex guarding threads list. */ void communicate(int client_fd, fd_set *base_rdfs, players_list_s **players_list, games_list_s **games_list, threads_list_s **threads_list, pthread_mutex_t *players_list_mutex, pthread_mutex_t *games_list_mutex, pthread_mutex_t *threads_list_mutex) { char buffer[MAX_MSG_SIZE]; ssize_t size; request_s request; memset(&request, 0, sizeof(request_s)); size = bulk_read(client_fd, buffer, MAX_MSG_SIZE); if (size == MAX_MSG_SIZE) { fprintf(stderr, "Message received from fd: %d\n", client_fd); string_to_request(buffer, &request); request_handler(client_fd, &request, base_rdfs, players_list, games_list, threads_list, players_list_mutex, games_list_mutex, threads_list_mutex); } if (size == 0) { fprintf(stderr, "End of file. Removing player. Closing descriptor: %d\n", client_fd); pthread_mutex_lock(players_list_mutex); remove_player_from_list2(players_list, client_fd); pthread_mutex_unlock(players_list_mutex); if (TEMP_FAILURE_RETRY(close(client_fd)) < 0) ERR("close"); FD_CLR(client_fd, base_rdfs); } if (size < 0) { fprintf(stderr, "Error. Removing player. Closing descriptor: %d\n", client_fd); pthread_mutex_lock(players_list_mutex); remove_player_from_list2(players_list, client_fd); pthread_mutex_unlock(players_list_mutex); if (TEMP_FAILURE_RETRY(close(client_fd)) < 0) ERR("close"); FD_CLR(client_fd, base_rdfs); } }
void server::HttpServer::worker(server::TcpServerConnection* connection) { server::HttpServerSession session; session.connection = connection; try { process_request(&session); check_request(&session); prepare_session(&session); request_handler(session); check_session_response(&session); send_response(&session); } catch(Exception& e) { bad_request(&session, e); } catch(std::bad_alloc& e) { } }
//------------------------------------------------------------------------------ /// Callback invoked when data has been received on the USB. //------------------------------------------------------------------------------ static void UsbDataReceived(unsigned int unused, unsigned char status, unsigned int received, unsigned int remaining) { // Check that data has been received successfully if (status == USBD_STATUS_SUCCESS) { // // Check if bytes have been discarded // if ((received == DATABUFFERSIZE) && (remaining > 0)) {} source_id = USB_SOURCE; if (modbus_dev_state == DEV_FREE) { for (unsigned short i = 0; i < received; i++) { *(puchMsg + i) = *(usbBuffer + i); } } // received_tmp = received; request_handler(received); } else { usb_state = USB_READ_ERROR; } }
/* * Opens a TCP stream socket on all interfaces with port number PORTNO. Saves * the fd number of the server socket in *socket_number. For each accepted * connection, calls request_handler with the accepted fd number. */ void serve_forever(int* socket_number, void (*request_handler)(int)) { struct sockaddr_in server_address, client_address; size_t client_address_length = sizeof(client_address); int client_socket_number; pid_t pid; *socket_number = socket(PF_INET, SOCK_STREAM, 0); if (*socket_number == -1) { fprintf(stderr, "Failed to create a new socket: error %d: %s\n", errno, strerror(errno)); exit(errno); } int socket_option = 1; if (setsockopt(*socket_number, SOL_SOCKET, SO_REUSEADDR, &socket_option, sizeof(socket_option)) == -1) { fprintf(stderr, "Failed to set socket options: error %d: %s\n", errno, strerror(errno)); exit(errno); } memset(&server_address, 0, sizeof(server_address)); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = INADDR_ANY; server_address.sin_port = htons(server_port); if (bind(*socket_number, (struct sockaddr*) &server_address, sizeof(server_address)) == -1) { fprintf(stderr, "Failed to bind on socket: error %d: %s\n", errno, strerror(errno)); exit(errno); } if (listen(*socket_number, 1024) == -1) { fprintf(stderr, "Failed to listen on socket: error %d: %s\n", errno, strerror(errno)); exit(errno); } printf("Listening on port %d...\n", server_port); while (1) { client_socket_number = accept(*socket_number, (struct sockaddr*) &client_address, (socklen_t*) &client_address_length); if (client_socket_number < 0) { fprintf(stderr, "Error accepting socket: error %d: %s\n", errno, strerror(errno)); continue; } printf("Accepted connection from %s on port %d\n", inet_ntoa(client_address.sin_addr), client_address.sin_port); pid = fork(); if (pid > 0) { close(client_socket_number); } else if (pid == 0) { signal(SIGINT, SIG_DFL); // Un-register signal handler (only parent should have it) close(*socket_number); request_handler(client_socket_number); close(client_socket_number); exit(EXIT_SUCCESS); } else { fprintf(stderr, "Failed to fork child: error %d: %s\n", errno, strerror(errno)); exit(errno); } } close(*socket_number); }
int main(void) try { // the thread group boost::shared_ptr< boost::thread_group > p_threads( boost::make_shared< boost::thread_group>()); // setup asio::io_service boost::shared_ptr< boost::asio::io_service > p_io_service( boost::make_shared< boost::asio::io_service >()); boost::shared_ptr< boost::asio::io_service::work > p_work( boost::make_shared< boost::asio::io_service::work >( boost::ref(*p_io_service))); // io_service threads { int n_threads = 1; while(0 < n_threads--) { p_threads->create_thread( boost::bind(&boost::asio::io_service::run, p_io_service)); } } // the shared work queue work_queue queue; // worker threads that will process the request; off the queue { int n_threads = 12; while(0 < n_threads--) { p_threads->create_thread( boost::bind(process_request, boost::ref(queue))); } } // setup the async server handler request_handler(queue); boost::shared_ptr< server > p_server_instance( boost::make_shared<server>( server::options(request_handler). address("0.0.0.0") .port("8800") .io_service(p_io_service) .reuse_address(true) .thread_pool( boost::make_shared<boost::network::utils::thread_pool>( 2 , p_io_service, p_threads)))); // setup clean shutdown boost::asio::signal_set signals(*p_io_service, SIGINT, SIGTERM); signals.async_wait(boost::bind(shut_me_down, _1, _2, p_server_instance)); // run the async server p_server_instance->run(); // we are stopped - shutting down p_threads->interrupt_all(); p_work.reset(); p_io_service->stop(); p_threads->join_all(); Log("Terminated normally"); exit(EXIT_SUCCESS); } catch(const std::exception& e) { Log("Abnormal termination - exception:"<<e.what()); exit(EXIT_FAILURE); }
int receive_message() { get_message(); if(message_rx[5] == 1 && message_rx[3] <= MAX_DIST) { switch(message_rx[2]) { case M_ERROR: break; case M_CHECK_ID: if(state < RECRUIT_REFERENCE) { if(check_id_handler ((uint8_t) message_rx[1], message_rx[3]) == 2) state = CONSTRUCT_ID; } break; case M_CHANGE_ID: if(message_rx[1] == id){ //reset, if I have to change ID RESET_COUNTER; message_out(EMPTY, id, M_CHANGE_ID); _delay_ms(250); state = CONSTRUCT_ID; } else { //drop the double id uint8_t faulty_id = message_rx[1]; struct list_node *n; if((n = exists(neighbours, &faulty_id, &comp_id_neigh)) != 0) remove_node(neighbours, n); } break; case M_ELECT_SEED_TOP: if(state == ELECT_SEED_TOP) return 1; break; case M_ELECT_SEED_BOTTOM: if(state == ELECT_SEED_BOTTOM) return 1; break; case M_NOT_ENOUGH_SEEDS: //if neighbour needs more seeders, new bottom election if((role != SEEDER) && (state == AWAIT_R_R || state == CHECK_SEEDER)) { role = BOTTOM_SEEDER; state = ELECT_SEED_BOTTOM; RESET_COUNTER; } break; case M_SEEDER: handle_seeder_m(message_rx[1]); break; case M_R_R_REQ_ATT: case M_R_R_ACK: case M_R_R_REQ_DIST: if(state >= RECRUIT_REFERENCE && message_rx[0] == id) request_handler(); break; case M_R_R_LISTENING: if(message_rx[0] == id && state == RECRUIT_REFERENCE) return 1; break; case M_R_R_DIST: if(message_rx[1] == id && state == RECRUIT_REFERENCE) return 1; break; case M_R_R_ABORT1: if(message_rx[1] == id && state == RECRUIT_REFERENCE) return 1; break; } } else { return E_NO_NEW_MESSAGE; } return 0; }
void swd::connection::handle_read(const boost::system::error_code& e, std::size_t bytes_transferred) { /** * If an error occurs then no new asynchronous operations are started. This * means that all shared_ptr references to the connection object will disappear * and the object will be destroyed automatically after this handler returns. * The connection class's destructor closes the socket. */ if (e) { return; } /** * Since there was no error we can start parsing the input now. The parser * fills the object request_ with data. */ boost::tribool result; boost::tie(result, boost::tuples::ignore) = request_parser_.parse( request_, buffer_.data(), buffer_.data() + bytes_transferred ); /** * If result is true the complete request is parsed. If it is false there was * an error. If it is indeterminate then the parsing is not complete yet and * the program will read more input and append it to the old request_ object. */ if (indeterminate(result)) { /* Not finished yet with this request, start reading again. */ this->start_read(); /* And don't process the input yet. */ return; } /* The handler used to process the reply. */ swd::reply_handler reply_handler(reply_); try { if (!result) { swd::log::i()->send(swd::warning, "Bad request from " + remote_address_.to_string()); throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST); } /* Try to add a profile for the request. */ try { swd::profile_ptr profile = swd::database::i()->get_profile( remote_address_.to_string(), request_->get_profile_id() ); request_->set_profile(profile); } catch (swd::exceptions::database_exception& e) { swd::log::i()->send(swd::uncritical_error, e.what()); throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST); } /* The handler used to process the incoming request. */ swd::request_handler request_handler(request_); /* Only continue processing the reply if it is signed correctly. */ if (!request_handler.valid_signature()) { swd::log::i()->send(swd::warning, "Bad signature from " + remote_address_.to_string()); throw swd::exceptions::connection_exception(STATUS_BAD_SIGNATURE); } /** * Before the request can be processed the input has to be transfered * from the encoded json string to a swd::parameters list. */ if (!request_handler.decode()) { swd::log::i()->send(swd::warning, "Bad json from " + remote_address_.to_string()); throw swd::exceptions::connection_exception(STATUS_BAD_JSON); } /* Process the request. */ std::vector<std::string> threats; try { if (swd::database::i()->is_flooding(request_->get_client_ip(), request_->get_profile_id())) { throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST); } threats = request_handler.process(); } catch (swd::exceptions::database_exception& e) { swd::log::i()->send(swd::uncritical_error, e.what()); /** * Problems with the database result in a bad request. If protection * is enabled access to the site will not be granted. */ throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST); } if (!threats.empty()) { reply_->set_threats(threats); reply_->set_status(STATUS_ATTACK); } else { reply_->set_status(STATUS_OK); } } catch(swd::exceptions::connection_exception& e) { reply_->set_status(e.code()); } /* Encode the reply. */ reply_handler.encode(); /* Send the answer to the client. */ if (ssl_) { boost::asio::async_write( ssl_socket_, reply_->to_buffers(), strand_.wrap( boost::bind( &connection::handle_write, shared_from_this(), boost::asio::placeholders::error ) ) ); } else { boost::asio::async_write( socket_, reply_->to_buffers(), strand_.wrap( boost::bind( &connection::handle_write, shared_from_this(), boost::asio::placeholders::error ) ) ); } }
void HTTPServer::handleRequest(HTTPRequestPtr& http_request, TCPConnectionPtr& tcp_conn) { if (! http_request->isValid()) { // the request is invalid or an error occured PION_LOG_INFO(m_logger, "Received an invalid HTTP request"); m_bad_request_handler(http_request, tcp_conn); return; } PION_LOG_DEBUG(m_logger, "Received a valid HTTP request"); // strip off trailing slash if the request has one std::string resource_requested(stripTrailingSlash(http_request->getResource())); // apply any redirection RedirectMap::const_iterator it = m_redirects.find(resource_requested); unsigned int num_redirects = 0; while (it != m_redirects.end()) { if (++num_redirects > MAX_REDIRECTS) { PION_LOG_ERROR(m_logger, "Maximum number of redirects (HTTPServer::MAX_REDIRECTS) exceeded for requested resource: " << http_request->getOriginalResource()); m_server_error_handler(http_request, tcp_conn, "Maximum number of redirects (HTTPServer::MAX_REDIRECTS) exceeded for requested resource"); return; } resource_requested = it->second; http_request->changeResource(resource_requested); it = m_redirects.find(resource_requested); } // if authentication activated, check current request if (m_auth) { // try to verify authentication if (! m_auth->handleRequest(http_request, tcp_conn)) { // the HTTP 401 message has already been sent by the authentication object PION_LOG_DEBUG(m_logger, "Authentication required for HTTP resource: " << resource_requested); if (http_request->getResource() != http_request->getOriginalResource()) { PION_LOG_DEBUG(m_logger, "Original resource requested was: " << http_request->getOriginalResource()); } return; } } // search for a handler matching the resource requested RequestHandler request_handler; if (findRequestHandler(resource_requested, request_handler)) { // try to handle the request try { request_handler(http_request, tcp_conn); PION_LOG_DEBUG(m_logger, "Found request handler for HTTP resource: " << resource_requested); if (http_request->getResource() != http_request->getOriginalResource()) { PION_LOG_DEBUG(m_logger, "Original resource requested was: " << http_request->getOriginalResource()); } } catch (HTTPResponseWriter::LostConnectionException& e) { // the connection was lost while or before sending the response PION_LOG_WARN(m_logger, "HTTP request handler: " << e.what()); tcp_conn->setLifecycle(TCPConnection::LIFECYCLE_CLOSE); // make sure it will get closed tcp_conn->finish(); } catch (std::bad_alloc&) { // propagate memory errors (FATAL) throw; } catch (std::exception& e) { // recover gracefully from other exceptions thrown request handlers PION_LOG_ERROR(m_logger, "HTTP request handler: " << e.what()); m_server_error_handler(http_request, tcp_conn, e.what()); } } else { // no web services found that could handle the request PION_LOG_INFO(m_logger, "No HTTP request handlers found for resource: " << resource_requested); if (http_request->getResource() != http_request->getOriginalResource()) { PION_LOG_DEBUG(m_logger, "Original resource requested was: " << http_request->getOriginalResource()); } m_not_found_handler(http_request, tcp_conn); } }
int main() { try { // the thread group auto threads(std::make_shared<boost::network::utils::thread_group>()); // setup asio::io_service auto io_service(std::make_shared<boost::asio::io_service>()); auto work(std::make_shared<boost::asio::io_service::work>(std::ref(*io_service))); // io_service threads { int n_threads = 5; while (0 < n_threads--) { threads->create_thread([=] () { io_service->run(); }); } } // the shared work queue work_queue queue; // worker threads that will process the request; off the queue { int n_threads = 5; while (0 < n_threads--) { threads->create_thread([&queue] () { process_request(queue); }); } } // setup the async server handler request_handler(queue); auto server(std::make_shared<server_data>( server::options(request_handler) .address("0.0.0.0") .port("8000") .io_service(io_service) .reuse_address(true) .thread_pool(std::make_shared<boost::network::utils::thread_pool>( 2, io_service, threads)))); // setup clean shutdown boost::asio::signal_set signals(*io_service, SIGINT, SIGTERM); signals.async_wait([=] (boost::system::error_code const &ec, int signal) { shut_me_down(ec, signal, server); }); // run the async server server->run(); work.reset(); io_service->stop(); threads->join_all(); std::cout << "Terminated normally" << std::endl; exit(EXIT_SUCCESS); } catch (const std::exception& e) { std::cerr << "Abnormal termination - exception:" << e.what() << std::endl; exit(EXIT_FAILURE); } }
void swd::connection::handle_read(const boost::system::error_code& e, std::size_t bytes_transferred) { /** * If an error occurs then no new asynchronous operations are started. This * means that all shared_ptr references to the connection object will disappear * and the object will be destroyed automatically after this handler returns. * The connection class's destructor closes the socket. */ if (e) { return; } /** * Since there was no error we can start parsing the input now. The parser * fills the object request_ with data. */ boost::tribool result; boost::tie(result, boost::tuples::ignore) = request_parser_.parse( request_, buffer_.data(), buffer_.data() + bytes_transferred ); /** * If result is true the complete request is parsed. If it is false there was * an error. If it is indeterminate then the parsing is not complete yet and * the program will read more input and append it to the old request_ object. */ if (indeterminate(result)) { /* Not finished yet with this request, start reading again. */ this->start_read(); /* And don't process the input yet. */ return; } /* The handler used to process the reply. */ swd::reply_handler reply_handler(reply_); try { if (!result) { swd::log::i()->send(swd::warning, "Bad request from " + remote_address_.to_string()); throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST); } /* Try to add a profile for the request. */ try { swd::profile_ptr profile = database_->get_profile( remote_address_.to_string(), request_->get_profile_id() ); request_->set_profile(profile); } catch (swd::exceptions::database_exception& e) { swd::log::i()->send(swd::uncritical_error, e.what()); throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST); } /* The handler used to process the incoming request. */ swd::request_handler request_handler(request_, cache_, storage_); /* Only continue processing the reply if it is signed correctly. */ if (!request_handler.valid_signature()) { swd::log::i()->send(swd::warning, "Bad signature from " + remote_address_.to_string()); throw swd::exceptions::connection_exception(STATUS_BAD_SIGNATURE); } /** * Before the request can be processed the input has to be transfered * from the encoded json string to a swd::parameters list. */ if (!request_handler.decode()) { swd::log::i()->send(swd::warning, "Bad json from " + remote_address_.to_string()); throw swd::exceptions::connection_exception(STATUS_BAD_JSON); } /* Check profile for outdated cache. */ swd::profile_ptr profile = request_->get_profile(); if (profile->is_cache_outdated()) { cache_->reset(profile->get_id()); } /* Process the request. */ std::vector<std::string> threats; try { swd::parameters parameters = request_->get_parameters(); /** * Check security limitations first. */ int max_params = swd::config::i()->get<int>("max-parameters"); if ((max_params > -1) && (parameters.size() > max_params)) { swd::log::i()->send(swd::notice, "Too many parameters"); throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST); } int max_length_path = swd::config::i()->get<int>("max-length-path"); int max_length_value = swd::config::i()->get<int>("max-length-value"); if ((max_length_path > -1) || (max_length_value > -1)) { for (swd::parameters::iterator it_parameter = parameters.begin(); it_parameter != parameters.end(); it_parameter++) { swd::parameter_ptr parameter(*it_parameter); if ((max_length_path > -1) && (parameter->get_path().length() > max_length_path)) { swd::log::i()->send(swd::notice, "Too long parameter path"); throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST); } if ((max_length_value > -1) && (parameter->get_value().length() > max_length_value)) { swd::log::i()->send(swd::notice, "Too long parameter value"); throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST); } } } if (profile->is_flooding_enabled()) { if (database_->is_flooding(request_->get_client_ip(), profile->get_id())) { swd::log::i()->send(swd::notice, "Too many requests"); throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST); } } /* Time to analyze the request. */ request_handler.process(); } catch (swd::exceptions::database_exception& e) { swd::log::i()->send(swd::uncritical_error, e.what()); /** * Problems with the database result in a bad request. If protection * is enabled access to the site will not be granted. */ throw swd::exceptions::connection_exception(STATUS_BAD_REQUEST); } if (profile->get_mode() == MODE_ACTIVE) { if (request_->is_threat()) { reply_->set_status(STATUS_CRITICAL_ATTACK); } else if (request_->has_threats()) { reply_->set_threats(request_handler.get_threats()); reply_->set_status(STATUS_ATTACK); } else { reply_->set_status(STATUS_OK); } } else { reply_->set_status(STATUS_OK); } } catch(swd::exceptions::connection_exception& e) { if (!request_->get_profile()) { reply_->set_status(STATUS_BAD_REQUEST); } else if (request_->get_profile()->get_mode() == MODE_ACTIVE) { reply_->set_status(e.code()); } else { reply_->set_status(STATUS_OK); } } /* Encode the reply. */ reply_handler.encode(); /* Send the answer to the client. */ if (ssl_) { boost::asio::async_write( ssl_socket_, reply_->to_buffers(), strand_.wrap( boost::bind( &connection::handle_write, shared_from_this(), boost::asio::placeholders::error ) ) ); } else { boost::asio::async_write( socket_, reply_->to_buffers(), strand_.wrap( boost::bind( &connection::handle_write, shared_from_this(), boost::asio::placeholders::error ) ) ); } }