connection_handle open(connection_info const&) { return connection_handle(); }
static int worker_server(worker *info) { /* server worker */ int nfds, fd, i; worker *w; int num = info->num; master_server *master_srv = info->master_srv; /* attach the shared mem */ int shmid; key_t key = master_srv->pid + num; if ((shmid = shmget(key, sizeof(worker), 0666)) < 0) { perror ("ERROR shmget"); exit (1); } /* attach it */ if ((w = shmat(shmid, NULL, 0)) == (char*) -1) { perror ("ERROR shmat"); exit (1); } /* process id */ w->pid = getpid(); /* worker process started */ printf (" * Worker process #%d is started.\n", num+1); /* pre-setup worker connections */ w->conns = connection_setup(master_srv); /* create a new event handler for this worker */ event_handler *ev_handler = events_create(master_srv->config->max_clients); /* share the event fd */ w->ev_handler.fd = ev_handler->fd; /* starting keep-alive clean-up thread */ printf (" * Starting keep-alive clean-up thread for worker #%d.\n", num+1); pthread_t thread_keep_alive; int rc_cleanup = pthread_create(&thread_keep_alive, NULL, worker_keep_alive_cleanup, w); /* starting heartbeat thread */ printf (" * Starting heartbeat thread for worker #%d.\n", num+1); pthread_t thread_heartbeat; int rc_heartbeat = pthread_create(&thread_heartbeat, NULL, worker_heartbeat, w); /* entering main loop... */ while (master_srv->running) { /* check for new data */ if ((nfds = events_wait(ev_handler, master_srv)) == -1) { perror ("ERROR epoll_pwait"); } for (i = 0; i < nfds; ++i) { /* data received */ fd = events_get_fd(ev_handler, i); connection *conn = w->conns[fd]; if (events_closed(ev_handler, i)) { /* the other end closed the connection */ conn->status = CONN_INACTIVE; printf (" * Other end closed the connection\n"); } else if (conn->status == CONN_INACTIVE) { /* this connection is inactive, initiate a new connection */ connection_start (master_srv, conn); } connection_handle (w, conn); /* closing */ if (conn->status == CONN_INACTIVE) { if (events_del_event(ev_handler, fd) == -1) { perror ("ERROR events_del_event"); } close (fd); } } } printf (" * Shutting down worker process #%d...\n", num+1); /* free event handler */ events_free (ev_handler, master_srv->config->max_clients); /* TODO: free all connections */ free (w->conns); /* free this workers memory */ worker_free (w); exit (0); }
void DataPlaneServer::readyRead(int) { memset(&client_addr, 0, sizeof(struct sockaddr_storage)); /* Create BIO */ bio = BIO_new_dgram(fd, BIO_NOCLOSE); /* Set and activate timeouts */ timeout.tv_sec = 5; timeout.tv_usec = 0; BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); ssl = SSL_new(ctx); SSL_set_bio(ssl, bio, bio); SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE); int dtlsRet; errno = 0; while ((dtlsRet = DTLSv1_listen(ssl, &client_addr)) <= 0) { if (errno != EAGAIN) { qWarning() << "DTLSv1_listen error"; qWarning() << SSL_get_error(ssl, dtlsRet); qWarning() << "Errno is" << errno; if (errno == EINVAL) { qWarning() << "!!!!!!!!!!! Your openssl library does not support DTLSv1_listen !!!!!!!!!!!"; qWarning() << "Cannot accept new connection"; SSL_shutdown(ssl); close(fd); SSL_free(ssl); ERR_remove_state(0); return; } } } QThread* workerThread = new QThread(); threads.append(workerThread); addrUnion infServer_addr; addrUnion infClient_addr; memcpy(&infServer_addr, &server_addr, sizeof(struct sockaddr_storage)); memcpy(&infClient_addr, &client_addr, sizeof(struct sockaddr_storage)); // get UID from friend using his IP to create worker thread // if IP is not in DB we close the connection char friendIp[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &infClient_addr.s6.sin6_addr, friendIp, INET6_ADDRSTRLEN); ConnectionInitiator* init = ConnectionInitiator::getInstance(); QString friendUid = qSql->getUidFromIP(QHostAddress(QString(friendIp))); ControlPlaneConnection* cp = init->getConnection(friendUid); if (friendUid.isEmpty() || cp->getMode() == Closed) { qDebug() << "friendUId NOT in DB or no control plane connection!"; SSL_shutdown(ssl); close(fd); //free(info); SSL_free(ssl); ERR_remove_state(0); qDebug("done, connection closed."); fflush(stdout); return; } // associate with dataplaneconnection DataPlaneConnection* dpc = init->getDpConnection(friendUid); ServerWorker* worker = new ServerWorker(infServer_addr, infClient_addr, ssl, dpc); worker->moveToThread(workerThread); connect(workerThread, SIGNAL(started()), worker, SLOT(connection_handle())); connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater())); //connect(worker, SIGNAL(bufferReady(const char*, int)), dpc, SLOT(readBuffer(const char*, int))); UnixSignalHandler* u = UnixSignalHandler::getInstance(); connect(u, SIGNAL(exiting()), workerThread, SLOT(quit())); workerThread->start(); }