Esempio n. 1
0
// Добавляем новое соединение в epoll
int acceptConnection() {
    struct sockaddr addr;
    socklen_t addrlen = sizeof(addr);
    int connectionfd = accept(socketfd, &addr, &addrlen);

    if (connectionfd == -1) {
        perror("acception connection error");
        return -1;
    }
    if (setNonBlock(connectionfd) == -1) {
        fprintf(stderr, "Making connection descriptor %d non-block error\n", connectionfd);
        return -1;
    }
    if (addToEpoll(epollfd, connectionfd, EPOLLET | EPOLLIN) == -1) {
        fprintf(stderr, "Adding connection to epoll\n");
        return -1;
    }
    addConnectionIntoList(connectionfd);
    return connectionfd;
}
Esempio n. 2
0
// прием соединения, если новых соединений нет или произошла ошибка то connectionfd == -1 
int acceptConnection(int epollfd, int socketfd, struct UserParams userParams){
  struct sockaddr addr;
  socklen_t addrlen = sizeof addr;

  int connectionfd = accept(socketfd, &addr, &addrlen);
  if (connectionfd == -1){
    perror ("failed to accept connection");
    return -1;
  }
  
  char host[NI_MAXHOST]; 
  char service[NI_MAXSERV]; 

  //резервирование символьного адреса и имени сервиса
  if(!getnameinfo(&addr, addrlen, host, sizeof host, service, sizeof service, NI_NUMERICHOST | NI_NUMERICSERV)){
  //вывод информации о полльзователе
    printf("new connection: %s:%s\n", host, service);
  }

  if (setNonBlock(connectionfd) == -1){
    fprintf(stderr, "failed to set socket %d nonblock", connectionfd);
    return -1;
  }
  //добавление в epol
  if (addToEpoll(epollfd, connectionfd) == -1){
    fprintf(stderr, "failed to add socket %d to epoll", connectionfd);
    return -1;
  }
  dprintf(connectionfd,"Enter login: "******"%d",connectionfd);
  DictInsert(userParams.login, conBuf, "");

  snprintf(conBuf, 4,"%d",connectionfd);
  DictInsert(userParams.fLogin, conBuf, "0");
  return 0;  
}
Esempio n. 3
0
///////////////////////////////////////////////////////////////////////////////
//
// MAIN
//
///////////////////////////////////////////////////////////////////////////////
int main(int argc, char *argv[]) {
    // Обработка сигнала
    struct sigaction act;
    memset(&act, 0, sizeof(act));
    act.sa_handler = handleSigInt;
    sigaction(SIGINT, &act, 0);

    // Проверка количества аргументов
    if (argc < 4) {
        fprintf(stderr, "Too few arguments\n");
        exit(EXIT_FAILURE);
    }

    // Количество потоков - 1й параметр запуска
    int numberOfWorkers = atoi(argv[1]);

    // Порт - 2й параметр запуска
    char port[4];
    strcpy(port, argv[2]);

    // Путь к файлу с паролями - 3й параметр запуска
    readPasswordsFromFile(argv[3]);

    // Инициализация connections
    memset(connections, 0, sizeof(connections));

    struct addrinfo* addresses = getAvailableAddresses(port);
    if (!addresses) 
        exit(EXIT_FAILURE);

    // Получаем дескриптор сокета
    int _socketfd = getSocket(addresses);
    if (_socketfd == -1) {
        exit(EXIT_FAILURE);
    }

    setSocketFd(_socketfd);

    // Начинаем слушать сокет
    if (listen(socketfd, SOMAXCONN) == -1) {
        perror("listen\n");
        exit(EXIT_FAILURE);
    }

    // Создаём потоки
    pthread_t workers[numberOfWorkers];
    pthread_mutex_t mutex;
    pthread_mutexattr_t mutexattr;
    pthread_mutexattr_init(&mutexattr);
    pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_ERRORCHECK);
    pthread_mutex_init(&mutex, &mutexattr);
    pthread_mutex_init(&connectionsMutex, &mutexattr);
    pthread_cond_t condition;
    pthread_cond_init(&condition, NULL);

    // Создаём отдельный поток для отслеживания таймаута соединений
    pthread_t timeoutWatcher;
    pthread_create(&timeoutWatcher, NULL, watchTimeout, NULL);

    // Создаём очередь
    struct Queue queue;
    initQueue(&queue, sizeof(struct epoll_event));

    struct WorkerArgs workerArgs;
    initWorkerArgs(&workerArgs, &queue, &mutex, &condition);

    for (int i = 0; i < sizeof(workers) / sizeof(pthread_t); i++) {
        pthread_create(&workers[i], NULL, worker, (void *) &workerArgs);
    }

    // Создаём epoll
    int _epollfd = epoll_create1(0);
    if (_epollfd == -1) {
        perror("epoll_create error\n");
        exit(EXIT_FAILURE);
    }

    setEpollFd(_epollfd);

    // Добавляем сокет в epoll
    if (addToEpoll(epollfd, socketfd, EPOLLET | EPOLLIN) == -1)
        exit(EXIT_FAILURE);

    int maxEventNum = numberOfWorkers;
    struct epoll_event events[maxEventNum];

    int timeout = -1;
    printf("Main thread: %d\n", (int)pthread_self());
    while(!done) {
        int eventsNumber = epoll_wait(epollfd, events, maxEventNum, timeout);
        if (!eventsNumber)
            printf("No events\n");
        for (int i = 0; i < eventsNumber; i++) {
            pthread_mutex_lock(&mutex);
            pushQueue(&queue, &events[i]);
            pthread_cond_signal(&condition);
            pthread_mutex_unlock(&mutex);
        }
    }

    // Освобождение ресурсов
    pthread_mutex_destroy(&connectionsMutex);
    pthread_mutex_destroy(&mutex);
    pthread_mutexattr_destroy(&mutexattr);
    free(passPairs);
    destroyQueue(&queue);
    close(socketfd);
    close(epollfd);
    printf("DONE!!!");
    return 0;
}
Esempio n. 4
0
int createPty(struct Connection *connection) {
    int ptm, pts;
    ptm = posix_openpt(O_RDWR);
    if (ptm == -1) {
        perror("creating new plm");
        return -1;
    }
    if (grantpt(ptm) == -1) {
        perror("granting pt access");
        return -1;
    }
    if (unlockpt(ptm) == -1) {
        perror("unlocking pt");
        return -1;
    }
    pts = open(ptsname(ptm), O_RDWR);
    if (pts == -1) {
        perror("opening pts");
        return -1;
    }
    if (setNonBlock(ptm) == -1) {
        fprintf(stderr, "Error: making ptm non-block\n");
        return -1;
    }
    if (setNonBlock(pts) == -1) {
        fprintf(stderr, "Error: making pts non-block\n");
        return -1;
    }

    connection->ptm = ptm;
    if (addToEpoll(epollfd, ptm, EPOLLET | EPOLLIN) == -1) {
        fprintf(stderr, "Error: adding ptm to epoll\n");
        return -1;
    }

    if (fork()) {
        if (close(pts) == -1) {
            perror("closing pts in parent process");
            return -1;
        }
    } else {
        if (close(ptm) == -1) {
            perror("closing ptm in child process");
            return -1;
        }
        struct termios oldSettings, newSettings;
        if (tcgetattr(pts, &oldSettings) == -1) {
            perror("getting old terminal settings\n");
            return -1;
        }
        newSettings = oldSettings;
        cfmakeraw(&newSettings);
        if (tcsetattr(pts, TCSANOW, &newSettings) == -1) {
            perror("setting new terminal settings\n");
            return -1;
        }
        close(0);
        close(1);
        close(2);

        dup(pts);
        dup(pts);
        dup(pts);

        close(pts);

        setsid();

        ioctl(0, TIOCSCTTY, 1);
        execvp("/bin/bash", NULL);
    }
    return 0;
}
Esempio n. 5
0
int main (int argc, char *argv[]){
          /*int c;
          FILE *pp;
          extern FILE *popen();
          if ( !(pp=popen("ls -l", "r")) ) 
            return 1;
 
          while ( (c=fgetc(pp)) != EOF ) {
          putc(c, stdout); 
          fflush(pp);
          }   
          pclose(pp);*/

  //пользовательскике данные
  struct UserParams userParams;
  Dict login = DictCreate();
  Dict fLogin = DictCreate();
  Dict location = DictCreate();;
  userParams.login = login;
  userParams.fLogin = fLogin;
  userParams.location = location;

  //параметры адреса
  printf("starting server\n");
  struct addrinfo hints; 
  memset(&hints, 0, sizeof hints);
  hints.ai_flags =  AI_PASSIVE;
  hints.ai_family = AF_UNSPEC; 
  hints.ai_socktype = SOCK_STREAM; 
  hints.ai_protocol = IPPROTO_TCP; 
  
  // получаение списка доступных адресов
  char* port = "8080";
  struct addrinfo* addresses = getAvilableAddresses(&hints, port); 
  if(!addresses)
    return EXIT_FAILURE;
  
  //коннект сокета
  int socketfd = assignSocket(addresses);
  if(!socketfd)
    return EXIT_FAILURE;


  if (setNonBlock(socketfd) == -1){
    perror("non_block");
    return EXIT_FAILURE;
  }


  if (listen (socketfd, SOMAXCONN) == -1){
    perror ("listen");
    return EXIT_FAILURE;
  }
  printf("listening port %s\n", port);
  
  //создание epoll
  int epollfd = epoll_create1(0);
  if (epollfd == -1){
    perror ("epoll_create");
    return EXIT_FAILURE;
  }


  if (addToEpoll(epollfd, socketfd) == -1)
    return EXIT_FAILURE;
  
  //регистрация обработчика событий
  signal(SIGINT, handleSignal);
    
  int maxEventNum = 8;
  struct epoll_event events[maxEventNum * sizeof(struct epoll_event)];
  //заполнение параметров для потоков
  struct Params params;
  pthread_mutex_init(&params.mutex, NULL);
  pthread_cond_init(&params.condvar, NULL); 
  params.end = 0;
  params.currrent = 0;
  params.epollfd = epollfd;
  params.events = events;
  params.socketfd = socketfd;
  params.userParams = userParams;
  pthread_t working[WORKING_THREADS_COUNT]; 
  for(int i = 0; i<WORKING_THREADS_COUNT; i++){   
    pthread_create(&working[i], NULL, workThread, &params);
  } 

  //обработка событий
  int timeout = -1 ;
  while(!done){
    if(params.currrent >= params.end){
      printf("waiting new events\n");
      int eventsNumber = epoll_wait(epollfd, events, maxEventNum, timeout);
      params.currrent = 0;
      params.end = eventsNumber;
      printf("Send\n");
      pthread_cond_signal(&params.condvar); 
    }
  }
  
  printf("server is going down\n");
  printf("closing connections\n");
  close(socketfd);
  close(epollfd);
  printf("done\n");
  return EXIT_SUCCESS;
}