Пример #1
0
static void
setup_server_env(void)
{
  setup_sock(listen_sock);
  cache_time_init();

  setup_static_env(server_name, server_port);
}
Пример #2
0
static void accept_cb(picoev_loop* loop, int fd, int revents, void* cb_arg)
{
  int newfd;
  assert((revents & PICOEV_READ) != 0);
  if ((newfd = accept(fd, NULL, NULL)) != -1) {
    setup_sock(newfd);
    picoev_add(loop, newfd, PICOEV_READ, 0, read_cb, NULL);
  }
}
Пример #3
0
static void accept_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
{
  int newfd = accept(picoev_w32_fd2sock(fd), NULL, NULL);
  if (newfd != -1) {
    int sock = picoev_w32_sock2fd(newfd);
    printf("connected: %d\n", sock);
    setup_sock(newfd);
    picoev_add(loop, sock, PICOEV_READ, TIMEOUT_SECS, rw_callback, NULL);
  }
}
Пример #4
0
int main(int argc, char * argv[]) {
  int sock;

  if (argc < 2) {
    printf("Usage: %s port\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  sock = setup_sock(atoi(argv[1]));
  echo(sock);
  close(sock);
}
Пример #5
0
int 
main(void)
{
  picoev_loop* loop;
  int listen_sock, flag;
  
  /* listen to port */
  assert((listen_sock = socket(AF_INET, SOCK_STREAM, 0)) != -1);
  flag = 1;
  assert(setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)) == 0);
  struct sockaddr_in listen_addr;
  listen_addr.sin_family = AF_INET;
  listen_addr.sin_port = htons(PORT);
  listen_addr.sin_addr.s_addr = htonl(HOST);
  assert(bind(listen_sock, (struct sockaddr*)&listen_addr, sizeof(listen_addr)) == 0);
  assert(listen(listen_sock, 5) == 0);
  setup_sock(listen_sock);
  
  /* init picoev */
  picoev_init(MAX_FDS);
  /* create loop */
  loop = picoev_create_loop(60);
  /* add listen socket */
  picoev_add(loop, listen_sock, PICOEV_READ, 0, accept_callback, NULL);

  /* Seccomp sandbox setup */
  sandbox_init();
  sandbox_setup();
  sandbox_lockdown();

  /* loop */
  while (1)
  {
    fputc('.', stdout);
    fflush(stdout);
    picoev_loop_once(loop, 10);
  }
  /* cleanup */
  picoev_destroy_loop(loop);
  picoev_deinit();
  
  return 0;
}
Пример #6
0
static void
accept_callback(picoev_loop* loop, int fd, int events, void* cb_arg)
{
  int client_fd;
  client_t *client;
  struct sockaddr_in client_addr;
  if ((events & PICOEV_TIMEOUT) != 0) {
    // time out
    // next turn or other process
    return;
  }else if ((events & PICOEV_READ) != 0) {
    socklen_t client_len = sizeof(client_addr);
#ifdef linux
    client_fd = accept4(fd, (struct sockaddr *)&client_addr, &client_len, SOCK_NONBLOCK | SOCK_CLOEXEC);
#else
    client_fd = accept(fd, (struct sockaddr *)&client_addr, &client_len);
#endif
    if (client_fd != -1) {
#ifdef DEBUG
      printf("accept fd %d \n", client_fd);
#endif
      setup_sock(client_fd);
      client = new_client_t(client_fd, client_addr);

      client->environ = Qnil;
      rb_gc_register_address(&client->environ);

      init_parser(client, server_name, server_port);

      picoev_add(loop, client_fd, PICOEV_READ, READ_LONG_TIMEOUT_SECS, r_callback, (void *)client);
    }else{
      if (errno != EAGAIN && errno != EWOULDBLOCK) {
	// TODO:
	// raise exception from errno
	/* rb_raise(); */
	/* write_error_log(__FILE__, __LINE__); */
	// die
	loop_done = 0;
      }
    }
  }
}
Пример #7
0
int main(int argc, char** argv)
{
  int ch, r, flag;
  struct sockaddr_in listen_addr;
  picoev_loop* loop;
  
  while ((ch = getopt(argc, argv, "p:")) != -1) {
    switch (ch) {
    case 'p':
      assert(sscanf(optarg, "%hu", &port) == 1);
      break;
    default:
      exit(1);
    }
  }
  
  listen_sock = socket(AF_INET, SOCK_STREAM, 0);
  assert(listen_sock != -1);
  flag = 1;
  r = setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
  assert(r == 0);
  listen_addr.sin_family = AF_INET;
  listen_addr.sin_port = htons(port);
  listen_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  r = bind(listen_sock, (struct sockaddr*)&listen_addr, sizeof(listen_addr));
  assert(r == 0);
  setup_sock(listen_sock);
  r = listen(listen_sock, SOMAXCONN);
  assert(r == 0);
  
  picoev_init(1048576 + 10);
  loop = picoev_create_loop(60);
  picoev_add(loop, listen_sock, PICOEV_READ, 0, accept_cb, NULL);
  while (1) {
    picoev_loop_once(loop, 10);
  }
  
  return 0;
}
Пример #8
0
void
CGI_prefork_server(const char *host, int port, const char *pidfile,
    int maxproc, int minidle, int maxidle, int maxreq,
    void (*callback)(void))
{
    int i, sock, fd;
    struct score_state message;
    struct score_board *scb;
    pid_t pid;
    FILE *fp;
    int pfd[2];
    char **realenv, **tmpenv;
    char *tmpbuf;
    extern char **environ;

    /* sanity check arguments */

    if (callback == 0) {
        syslog(LOG_ERR, "CGI_prefork_server(): null callback "
            "function pointer");
        return;
    }

    if (minidle <= 0) {
        minidle = 2;
    }
    if (maxidle <= minidle) {
        maxidle = minidle + 2;
    }
    if (maxproc <= 0) {
        maxproc = maxidle;
    }
    if (maxproc > SCORE_MAX_PROC) {
        maxproc = SCORE_MAX_PROC;
    }
    syslog(LOG_INFO, "CGI_prefork_server(): maxproc = %d, minidle = %d, "
        "maxidle = %d, maxreq = %d", maxproc, minidle, maxidle, maxreq);

    /* parent puts self into the background */

    if (fork() != 0) {
        _exit(0);
    }
    setsid();
    set_handler(SIGTERM, terminate);
    set_handler(SIGCHLD, child_handler);
    if ( freopen("/dev/null", "r", stdin) != 0 )
        printf("freopen error\n");
    if ( freopen("/dev/null", "w", stdout) != 0 )
        printf("freopen2 error\n");
    /* write our pid to pidfile */

    if (pidfile != 0 && *pidfile != 0 &&
        (fp = fopen(pidfile, "w")) != 0)
    {
        fprintf(fp, "%d\n", getpid());
        fclose(fp);
    }

    /* create child process scoreboard */

    scb = score_new(maxproc, minidle, maxidle);

    /* parent opens the listen socket, children accept() connections */

    if ((sock = setup_sock(host, port)) < 0) {
        syslog(LOG_ERR, "CGI_prefork_server(): setup_sock() failed: %m");
        return;
    }

    /* open pipe to receive messages from child processes */

    if ( pipe(pfd) != 0 )
        printf("pipe error\n");

    /* parent manages child processes */

    for (;;) {

        /* fork child if necessary */

        if (scb->numidle < scb->minidle && scb->numproc < scb->maxproc) {
            if ((pid = fork()) == 0) {
                break;
            }
            else if (pid > 0) {
                score_add(scb, pid);
                continue;
            }
            else {
                syslog(LOG_ERR, "CGI_prefork_server(): fork() failed: %m");
                if (scb->numproc == 0) {
                    return;
                }
            }
        }

        /*
         * read status message from child.  The read() call returns with
         * an error if we catch SIGCHLD or SIGTERM.
         */

        if (child_exited == 0 && terminate_flag == 0 &&
            read(pfd[0], &message, sizeof(message)) == sizeof(message))
        {
            score_update(scb, &message);
        }

        /* kill everything and exit if we got SIGTERM */

        if (terminate_flag != 0) {
            set_handler(SIGTERM, SIG_IGN);
            kill(0, SIGTERM);        /* kill process group */
            while(wait(0) >= 0)
                ;
            exit(0);
        }

        /* kill idle child if necessary */

        if (scb->numidle > scb->maxidle) {
            score_kill(scb);
        }

        /* wait for exited children */

        child_exited = 0;
        while ((pid = waitpid(-1, 0, WNOHANG)) > 0) {
            score_remove(scb, pid);
        }
    }

    /* child handles maxreq requests and exits */

    set_handler(SIGTERM, SIG_DFL);
    set_handler(SIGCHLD, SIG_DFL);
    close(pfd[0]);
    message.pid = getpid();
    realenv = environ;

    for (i = 0; i < maxreq || maxreq <= 0; i++) {

        /* accept connection from SCGI client (httpd) */

        if ((fd = accept(sock, 0, 0)) < 0) {
            syslog(LOG_ERR, "CGI_prefork_server(): accept() failed: %m");
            break;
        }

        /* notify parent we are busy */

        message.state = SCORE_BUSY;
        if ( write(pfd[1], &message, sizeof(message)) != sizeof(message) )
            printf("write error\n");

        /* redirect stdin and stdout to socket */

        dup2(fd, 0);
        dup2(fd, 1);
        close(fd);

        /* read environment and call callback */

        if ((tmpenv = read_env()) != 0) {
            tmpbuf = tmpenv[0];
            environ = tmpenv;
            callback();
        }
        else {
            fputs("Content-type: text/plain\r\n\r\n"
                "CGI_prefork_server() could not read environment.\r\n",
                stdout);
            syslog(LOG_ERR, "CGI_prefork_server(): could not read "
                "environment");
        }

        /* close socket and restore environment */

        if ( freopen("/dev/null", "r", stdin) != 0 )
            printf("freopen3 error\n");
        if ( freopen("/dev/null", "w", stdout) != 0 )
            printf("freopen4 error\n");
        environ = realenv;
        if (tmpenv != 0) {
            free(tmpbuf);
            free(tmpenv);
        }

        /* notify parent we are idle */

        message.state = SCORE_IDLE;
       if ( write(pfd[1], &message, sizeof(message)) != sizeof(message) )
           printf("write2 error\n");
    }
    _exit(0);
}