예제 #1
0
void handle_worker_response(Worker_handle worker_handle, const Response_msg& resp) 
{

  // Master node has received a response from one of its workers.
  // Here we directly return this response to the client.

  DLOG(INFO) << ">>>Master received a response from a worker: [" << resp.get_tag() << ":" << resp.get_response() << "]" << std::endl;

  Client_handle client = mstate.tagClientMap[resp.get_tag()];
  send_client_response(client, resp);
  DLOG(INFO) << "<<Master send response back to client: " << client << std::endl;

  mstate.num_pending_client_requests --;
  DLOG(INFO) << "pending_client_requests: " <<  mstate.num_pending_client_requests << std::endl;

  //store to cache
  int tag = resp.get_tag(); 
  std::string req_string = mstate.tagReqStringMap[tag];
  cache_manager.cacheMap[req_string] = resp.get_response();


  //find the worker
  for(unsigned int i = 0; i< mstate.my_workers.size(); i++)
  {
    if(mstate.my_workers[i].worker_handle == worker_handle)
    {
      // update mstate
      mstate.handle_work_done(resp, i);
      break;
    }
  }
  // re-dispatching vip queue 
  for (unsigned int i = 0; i < mstate.requests_queue_vip.size(); i++)
  {
    Request_info req = mstate.requests_queue_vip.front();
    DLOG(INFO) << "deque(vip):" << req.client_req.get_request_string()<< std::endl;
    mstate.requests_queue_vip.pop();
    handle_client_request(req.client_handle, req.client_req);
  }
  // re-dispatching queue
  for (unsigned int i = 0; i < mstate.requests_queue.size(); i++)
  {
    Request_info req = mstate.requests_queue.front(); 
    DLOG(INFO) << "deque:" << req.client_req.get_request_string()<< std::endl;
    mstate.requests_queue.pop();
    handle_client_request(req.client_handle, req.client_req);
  }

  return;

}
예제 #2
0
int main(int argc, char** argv) {
  int chdev = -1;

  try {
    if (argc != 2) {
      THROW("incorrect number of arguments");
    }

    // open the character device
    CHECK((chdev = open(argv[1], O_RDWR)));

    // handles client requests
    try {
      while (handle_client_request(chdev));
    }
    catch (std::exception& e) {
      close(chdev);
      std::cerr << e.what() << std::endl;
      exit(1);
    }

    // close the client
    CHECK(close((chdev)));
    exit(0);
  }
  catch (std::exception& e) {
    close(chdev);
    std::cerr << e.what() << std::endl;
    exit(1);
  }

  return 0;
}
예제 #3
0
void handle_event(const struct epoll_event *event) {
	struct signalfd_siginfo signalinfo;

	if (event->data.fd == sig_fd) {
		ssize_t n;
		if ((n = read(event->data.fd, &signalinfo, sizeof(signalinfo))) < 0) {
			syslog(LOG_ERR, "Error reading from signal fd: %s\n", strerror(errno));
			return;
		}
		if (n < sizeof(signalinfo)) {
			syslog(LOG_ERR, "Partial read(2) on signal fd detected (%zu/%zu)\n", n, sizeof(signalinfo));
			return;
		}
		if (signalinfo.ssi_signo == SIGHUP) {
			sighup_rehash();
			return;
		} else if (signalinfo.ssi_signo == SIGTERM) {
			syslog(LOG_INFO, "Got SIGTERM, exiting...\n");
			leave();
		} else if (signalinfo.ssi_signo == SIGINT) {
			syslog(LOG_INFO, "Got SIGINT, exiting...\n");
			leave();
		} else {
			syslog(LOG_INFO, "Unexpected signal received: %s\n", strsignal(signalinfo.ssi_signo));
		}
	}

	if (event->data.fd == sockfd) {
		int clientfd;
		if ((clientfd = accept(sockfd, NULL, NULL)) < 0) {
			syslog(LOG_ERR, "Error accepting new client: %s\n", strerror(errno));
			return;
		}

		int optval = 1;
		if (setsockopt(clientfd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)) < 0) {
			syslog(LOG_ERR, "Error setting SO_PASSCRED on new client: %s\n", strerror(errno));
			close(clientfd);
			return;
		}

		struct epoll_event event;
		event.events = EPOLLIN | EPOLLET;
		event.data.fd = clientfd;

		if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, clientfd, &event) < 0) {
			syslog(LOG_ERR, "Error adding new client to epoll set: %s\n", strerror(errno));
			close(clientfd);
		}

		return;
	}

	handle_client_request(event->data.fd);
}
예제 #4
0
static void handle_client_data(int fd) {
	int r;
	if((r = read(fd, client_data[fd].buf+client_data[fd].pos, 1024-client_data[fd].pos)) > 0) {
		client_data[fd].pos += r;
		if(client_data[fd].pos >= 4 && !strncmp(client_data[fd].buf+client_data[fd].pos-4, "\r\n\r\n", 4)) {
			client_data[fd].buf[client_data[fd].pos] = '\0';
			client_data[fd].state = CLIENT_INACTIVE;
			handle_client_request(fd, client_data[fd].buf);
			return;
		}
	} else {
		client_data[fd].state = CLIENT_INACTIVE;
		close(fd);
	}
}
/* thread: the request handler */
void handle_request(void *args){
	HandlerArgs *handlerArgs = (HandlerArgs*)args;
	char *recv_text = recv_once(handlerArgs->sockfd);
	int isServerRequest = is_server_request(recv_text);
	if(isServerRequest == TRUE){
		handle_server_request(handlerArgs->sockfd, recv_text, handlerArgs->own_service_table, handlerArgs->service_list, handlerArgs->own_server_name);
	}
	else if(isServerRequest == FALSE){
		handle_client_request(handlerArgs->sockfd, recv_text, handlerArgs->own_service_table, handlerArgs->service_list, handlerArgs->own_server_name);
	}
	else{
		printf("no infomation recived\n");
		printf("connection closed by client\n");
	}
	
	if(recv_text != NULL)
		free(recv_text);
	free(args);
	pthread_exit(NULL);
}
예제 #6
0
int
main (int argc, char *argv[])
{
    int sfd, s;
    int efd;
    struct epoll_event event;
    struct epoll_event *events;
    
    if (argc != 2)
    {
        fprintf (stderr, "Usage: %s [port]\n", argv[0]);
        exit (EXIT_FAILURE);
    }
    
    sfd = create_and_bind (argv[1]);
    if (sfd == -1)
        abort ();
    
    s = make_socket_non_blocking (sfd);
    if (s == -1)
        abort ();
    
    s = listen (sfd, SOMAXCONN);
    if (s == -1)
    {
        perror ("listen");
        abort ();
    }
    
    efd = epoll_create1 (0);
    if (efd == -1)
    {
        perror ("epoll_create");
        abort ();
    }
    
    event.data.fd = sfd;
    event.events = EPOLLIN | EPOLLET;
    s = epoll_ctl (efd, EPOLL_CTL_ADD, sfd, &event);
    if (s == -1)
    {
        perror ("epoll_ctl");
        abort ();
    }
    
    /* Buffer where events are returned */
    events = calloc (MAXEVENTS, sizeof event);
    
    /* The event loop */
    while (1)
    {
        int n, i;
        
        n = epoll_wait (efd, events, MAXEVENTS, -1);
        for (i = 0; i < n; i++)
        {
            if ((events[i].events & EPOLLERR) ||
                (events[i].events & EPOLLHUP) ||
                (!(events[i].events & EPOLLIN)))
            {
                /* An error has occured on this fd, or the socket is not
                 ready for reading (why were we notified then?) */
                fprintf (stderr, "epoll error\n");
                close (events[i].data.fd);
                continue;
            }
            
            else if (sfd == events[i].data.fd)
            {
                /* We have a notification on the listening socket, which
                 means one or more incoming connections. */
                while (1)
                {
                    struct sockaddr in_addr;
                    socklen_t in_len;
                    int infd;
                    char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
                    
                    in_len = sizeof in_addr;
                    infd = accept (sfd, &in_addr, &in_len);
                    if (infd == -1)
                    {
                        if ((errno == EAGAIN) ||
                            (errno == EWOULDBLOCK))
                        {
                            /* We have processed all incoming
                             connections. */
                            break;
                        }
                        else
                        {
                            perror ("accept");
                            break;
                        }
                    }
                    
                    s = getnameinfo (&in_addr, in_len,
                                     hbuf, sizeof hbuf,
                                     sbuf, sizeof sbuf,
                                     NI_NUMERICHOST | NI_NUMERICSERV);
                    if (s == 0)
                    {
                        printf("Accepted connection on descriptor %d "
                               "(host=%s, port=%s)\n", infd, hbuf, sbuf);
                    }
                    
                    /* Make the incoming socket non-blocking and add it to the
                     list of fds to monitor. */
                    s = make_socket_non_blocking (infd);
                    if (s == -1)
                        abort ();
                    
                    event.data.fd = infd;
                    event.events = EPOLLIN | EPOLLET;
                    s = epoll_ctl (efd, EPOLL_CTL_ADD, infd, &event);
                    if (s == -1)
                    {
                        perror ("epoll_ctl");
                        abort ();
                    }
                }
                continue;
            }
            else
            {
                /* We have data on the fd waiting to be read. Read and
                 display it. We must read whatever data is available
                 completely, as we are running in edge-triggered mode
                 and won't get a notification again for the same
                 data. */
                int done = 0;
                
                while (1)
                {
                    ssize_t count;
                    char buf[512];
                    
                    count = read (events[i].data.fd, buf, sizeof buf);
                    if (count == -1)
                    {
                        /* If errno == EAGAIN, that means we have read all
                         data. So go back to the main loop. */
                        if (errno != EAGAIN)
                        {
                            perror ("read");
                            done = 1;
                        }
                        break;
                    }
                    else if (count == 0)
                    {
                        /* End of file. The remote has closed the
                         connection. */
                        done = 1;
                        break;
                    }
                    
                    /* Write the buffer to standard output */
                    handle_client_request(buf, count);
                }
                
                if (done)
                {
                    printf ("Closed connection on descriptor %d\n",
                            events[i].data.fd);
                    
                    /* Closing the descriptor will make epoll remove it
                     from the set of descriptors which are monitored. */
                    close (events[i].data.fd);
                }
            }
        }
    }
    
    free (events);
    
    close (sfd);
    
    return EXIT_SUCCESS;
}
예제 #7
0
void handle_client(int sockfd){
	handle_client_request(sockfd);
	handle_client_response(sockfd);
}
예제 #8
0
void
handle_server_events(server_t *server)
{
    // respond to events
    memset(&server->ke, 0, sizeof(server->ke));
    if (kevent(server->kq, NULL, 0, &server->ke, 1, NULL) <= 0) {
        usleep(5000);
        return;
    }

    if (server->ke.ident == (uintptr_t)server->sock) {
        // client connection
        int cl_sock;
        struct sockaddr_in c;
        socklen_t len;

        if ((cl_sock = accept(server->sock,
                        (struct sockaddr *)&c, &len)) == -1)
            err(EX_UNAVAILABLE, "accept");

        // init client
        client_conn_t *conn = calloc(1, sizeof(client_conn_t));
        conn->sock = cl_sock;
        memcpy(&conn->addr, &c.sin_addr, sizeof(c.sin_addr));
        conn->client = init_client();
        server->clients[server->client_count++] = conn;

        // listen to the client socket
        EV_SET(&server->ke, conn->sock, EVFILT_READ, EV_ADD, 0, 0, NULL);
        if (kevent(server->kq, &server->ke, 1, NULL, 0, NULL) == -1)
            err(EX_UNAVAILABLE, "kevent add user");

        fprintf(stderr, "connection from %s\n", inet_ntoa(c.sin_addr));
    } else if (server->ke.ident == 0) {
        // game update timer fired
        update_server(server);
    } else {
        // client data
        client_conn_t *conn = find_client(server, server->ke.ident);

        // read the data
        char buf[1024];
        memset(&buf, 0, sizeof(buf));
        int n = read(conn->sock, buf, sizeof(buf));

        // not ready yet
        if (n == -1)
            return;

        // EOF - disconnect user
        if (n == 0) {
            EV_SET(&server->ke, conn->sock, EVFILT_READ, EV_DELETE, 0, 0,
                    NULL);
            if (kevent(server->kq, &server->ke, 1, 0, 0, NULL) == -1)
                err(EX_UNAVAILABLE, "disconnect user");

            fprintf(stderr, "%s logged out\n", conn->client->username);
            close(conn->sock);

            if (conn->client)
                if (conn->client->entity)
                    conn->client->entity->dead = true;

            free(conn);

            return;
        }

        // handle the data
        handle_client_request(server, conn, buf, n);
    }
}