⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fatcontroller.cpp

📁 一个UNIX/LINUX下的基于内容的过滤服务器源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            }            catch (exception& e) {}            _exit(rc); // baby go bye bye        }        else {  // must be parent            close(sv[1]);            addChild(getChildSlot(), sv[0], child_pid);            #ifdef DGDEBUG                std::cout << "Preforked parent added child to list" << std::endl;            #endif        }    }    return 1;  // parent returning}void FatController::tidyUpForChild() {    struct sigaction sa;    memset(&sa, 0, sizeof(sa));    sa.sa_handler = SIG_DFL;    if (sigaction(SIGTERM, &sa, NULL)) {  // restore sig handler                                          // in child process        #ifdef DGDEBUG            std::cerr << "Error resetting signal for SIGTERM" << std::endl;        #endif        syslog(LOG_ERR, "%s","Error resetting signal for SIGTERM");    }    memset(&sa, 0, sizeof(sa));    sa.sa_handler = SIG_IGN;    if (sigaction(SIGUSR1, &sa, NULL)) {  // restore sig handler                                          // in child process        #ifdef DGDEBUG            std::cerr << "Error resetting signal for SIGUSR1" << std::endl;        #endif        syslog(LOG_ERR, "%s","Error resetting signal for SIGUSR1");    }    memset(&sa, 0, sizeof(sa));    sa.sa_handler = &sig_hup;    if (sigaction(SIGHUP, &sa, NULL)) {  // restore sig handler                                          // in child process        #ifdef DGDEBUG            std::cerr << "Error resetting signal for SIGHUP" << std::endl;        #endif        syslog(LOG_ERR, "%s","Error resetting signal for SIGHUP");    }    // now close open socket pairs don't need    for (int i = 0; i < o.max_children; i++) {        if (pids[i + 1].fd != -1) {            try {                close(pids[i + 1].fd);            } catch (exception& e) {}        }    }    delete[] childrenpids;    delete[] childrenstates;    delete[] pids;  // 3 deletes good, memory leaks bad}int FatController::handleConnections(int pipe) {    ConnectionHandler h;  // the class that handles the connections    String ip;    bool toldparentready = false;    int cycle = o.maxage_children;    int stat = 0;    reloadconfig = false;    while(cycle-- && !reloadconfig)  {        if (!toldparentready) {            if (sendReadyStatus(pipe) == -1) {  // non-blocking (timed)                #ifdef DGDEBUG                std::cout << "parent timed out telling it we're ready" << std::endl;                #endif                break;  // parent timed out telling it we're ready                // so either parent gone or problem so lets exit this joint            }            toldparentready = true;        }        if (!getFDFromParent(pipe)) {// blocks waiting for a few mins            continue;        }        toldparentready = false;        if (peersockfd < 1 || peersockip.length() < 7) {            continue;        }        h.handleConnection(peersockfd, peersockip, peersockport);  // deal with the connection        close(peersockfd);    }    #ifdef DGDEBUG        if (reloadconfig) {            std::cout << "child been told to exit by hup" << std::endl;        }    #endif    if (!toldparentready) {        stat = 2;    }    return stat;}int FatController::getChildSlot() {    int i;    for(i = 0; i < o.max_children; i++) {        if (childrenpids[i] == -1) {            return i;        }    }    return -1;}void FatController::addChild(int pos, int fd, pid_t child_pid) {    childrenpids[pos] = (int)child_pid;    childrenstates[pos] = 4; // busy waiting for init    numchildren++;    busychildren++;    waitingfor++;    pids[pos + 1].fd = fd;}void FatController::cullChildren(int num) {    #ifdef DGDEBUG        cout << "culling childs:" << num << endl;    #endif    int i;    int count = 0;    for(i = o.max_children - 1; i >= 0; i--) {        if (childrenstates[i] == 0) {            kill(childrenpids[i], SIGTERM);            count++;            childrenstates[i] = -2; // dieing            numchildren--;            try {                close(pids[i + 1].fd);            } catch (exception& e) {}            pids[i + 1].fd = -1;            if (count >= num) {                break;            }        }    }}void FatController::killAllChildren() {    #ifdef DGDEBUG        cout << "killing all childs:" << endl;    #endif    for(int i = o.max_children - 1; i >= 0; i--) {        if (childrenstates[i] >= 0) {            kill(childrenpids[i], SIGTERM);            childrenstates[i] = -2; // dieing            numchildren--;        }    }}void FatController::hupAllChildren() {    #ifdef DGDEBUG        cout << "huping all childs:" << endl;    #endif    for(int i = o.max_children - 1; i >= 0; i--) {        if (childrenstates[i] >= 0) {            kill(childrenpids[i], SIGHUP);        }    }}bool FatController::checkKidReadyStatus(int tofind) {    bool found = false;    char* buf = new char[5];    int rc = -1; // for compiler warnings    for(int f = 1; f <= o.max_children; f++) {        if (tofind < 1) {            break;  // no point looping through all if all found        }        if (pids[f].fd == -1) {            continue;        }        if ((pids[f].revents & POLLIN) > 0) {            if (childrenstates[f - 1] < 0) {                tofind--;                continue;            }            try {                rc = getLineFromFD(pids[f].fd, buf, 4, 100);            }            catch (exception& e) {                kill(childrenpids[f - 1], SIGTERM);                deleteChild(childrenpids[f - 1], -1);                tofind--;                continue;            }            if (rc > 0) {                if (buf[0] == '2') {                    if (childrenstates[f - 1] == 4) {                        waitingfor--;                    }                    childrenstates[f - 1] = 0;                    busychildren--;                    tofind--;                }            }            else { // child -> parent communications failure so kill it                kill(childrenpids[f - 1], SIGTERM);                deleteChild(childrenpids[f - 1], -1);                tofind--;            }        }        if (childrenstates[f - 1] == 0) {            found = true;        }    }    // if unbusy found then true otherwise false    delete[] buf;    return found;}void FatController::deleteChild(int child_pid, int stat) {    int i;    for(i = 0; i < o.max_children; i++) {        if (childrenpids[i] == child_pid) {            childrenpids[i] = -1;            if (childrenstates[i] == 1) {                if (stat == 2) {                     busychildren--;                }                else {                    busychildren--;  // should only happen if kid goes screwy                }            }            if (childrenstates[i] != -2) {  // -2 is when its been culled                numchildren--;              // so no need to duplicate                try {                    close(pids[i + 1].fd);      // closing etc                } catch (exception& e) {}                pids[i + 1].fd = -1;            }            childrenstates[i] = -1; // unused            break;        }    }  // never should happen that passed pid not know       // unless its the logger or url cache process in which case we}       // don't want to do anything anyway and this can only happen       // when shutting down or restartingint FatController::getFreeChild() {  // check that there is 1 free done                                     // before calling    int i;    for(i = 0; i < o.max_children; i++) {        if (childrenstates[i] == 0) {  // not busy (free)            return i;        }    }    return -1;}int FatController::sendReadyStatus(int pipe) { // blocks until timeout    String message = "2\n";    try {        if (!writeToFd(pipe, message.toCharArray(), message.length(), 15)) {            return -1;        }    }    catch (exception& e) {        return -1;    }    return 0;}void FatController::tellChildAccept(int num) {    int fd = pids[num + 1].fd;    String message = "G\n";    try {        writeToFd(fd, message.toCharArray(), message.length(), 5);    } catch (exception& e) {        kill(childrenpids[num], SIGTERM);        deleteChild(childrenpids[num], -1);        return;    }    char* buf = new char[5];    try {        getLineFromFD(fd, buf, 4, 5);    } catch (exception& e) {        kill(childrenpids[num], SIGTERM);        deleteChild(childrenpids[num], -1);        delete[] buf;        return;    }    delete[] buf; // no need to check as the very fact the child sent                  // something back is a good sign    busychildren++;    childrenstates[num] = 1; // busy}bool FatController::getFDFromParent(int fd) {    String message;    char* buf = new char[5];    int rc;    try {        rc = getLineFromFD(fd, buf, 4, 360);  // blocks for a few mins    }    catch (exception& e) {        delete[] buf;        reloadconfig = true;        return false;    }    // that way if child does nothing for a long time it will eventually    // exit reducing the forkpool depending on o.maxage_children which is    // usually 500 so max time a child hangs around is lonngggg    // it needs to be a long block to stop the machine needing to page in    // the process    if (rc < 1) {        delete[] buf;        return false;    }    if (buf[0] != 'G') {        delete[] buf;        return false;    }    delete[] buf;    sockaddr_in peer_adr_inet;    socklen_t peer_adr_inet_length = sizeof(struct sockaddr_in);    // OS X defines accept as:    // int accept(int s, struct sockaddr *addr, int *addrlen);    // but everyone else as:    // int accept(int s, struct sockaddr *addr, socklen_t *addrlen);#ifdef __DARWIN    peersockfd = accept(serversock.getFD(), (struct sockaddr *) &peer_adr_inet, (int *)&peer_adr_inet_length);#else    peersockfd = accept(serversock.getFD(), (struct sockaddr *) &peer_adr_inet, &peer_adr_inet_length);#endif    peersockip = inet_ntoa(peer_adr_inet.sin_addr);    peersockport = ntohs(peer_adr_inet.sin_port);    // get the new socket which    // describes the accepted connection    try {        writeToFd(fd, "K\n", 2, 10);  // need to make parent wait for OK                                  // so effectively providing a lock    }    catch (exception& e) {        try {          close(peersockfd);        }        catch (exception& e) {        }        return false;    }    if (peersock.getFD() < 1) {        if (o.logconerror == 1) {            syslog(LOG_INFO, "%s","Error accepting. (Ignorable)");        }        return false;    }    return true;}bool FatController::writeToFd(int fd, const char* buff, int len, int timeout) {    int actuallysent = 0;    int sent;    while (actuallysent < len) {        if (!readyForOutput(fd, timeout)) {            return false;        }        sent = send(fd, buff + actuallysent, len - actuallysent, 0);        if (sent < 0) {            if (errno == EINTR && !reloadconfig) {                continue;  // was interupted by signal so restart            }            return false;        }        if (sent == 0) {            return false; // other end is closed        }        actuallysent += sent;    }    return true;}bool FatController::readyForOutput(int fd, int timeout) {    fd_set fdSet;    FD_ZERO(&fdSet);  // clear the set    FD_SET(fd, &fdSet);  // add fd to the set

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -