Example #1
0
int CFTestD_StartServer(CFTestD_Config *config)
{
    int ret = -1;

    bool tls_init_ok = ServerTLSInitialize(config->priv_key, config->pub_key, &(config->ssl_ctx));
    if (!tls_init_ok)
    {
        return -1;
    }

    int sd = InitServer(CFTESTD_QUEUE_SIZE, config->address);

    int selected = 0;
    while (!TERMINATE && (selected != -1))
    {
        selected = WaitForIncoming(sd, WAIT_CHECK_TIMEOUT);

        if (selected > 0)
        {
            Log(LOG_LEVEL_DEBUG, "select(): %d", selected);
            CFTestD_AcceptAndHandle(sd, config);
        }
    }
    if (!TERMINATE)
    {
        Log(LOG_LEVEL_ERR,
            "Error while waiting for connections. (select: %s)",
            GetErrorStr());
    }
    else
    {
        ret = 0;
    }

    Log(LOG_LEVEL_NOTICE, "Cleaning up and exiting...");
    if (sd != -1)
    {
        Log(LOG_LEVEL_VERBOSE, "Closing listening socket");
        cf_closesocket(sd);
    }

    return ret;
}
/**
 *  @retval >0 Number of threads still working
 *  @retval 0  All threads are done
 *  @retval -1 Server didn't run
 */
int StartServer(EvalContext *ctx, Policy **policy, GenericAgentConfig *config)
{
    InitSignals();
    ServerTLSInitialize();
    int sd = SetServerListenState(ctx, QUEUESIZE, SERVER_LISTEN, &InitServer);

    /* Necessary for our use of select() to work in WaitForIncoming(): */
    assert(sd < sizeof(fd_set) * CHAR_BIT &&
           GetSignalPipe() < sizeof(fd_set) * CHAR_BIT);

    Policy *server_cfengine_policy = PolicyNew();
    CfLock thislock = AcquireServerLock(ctx, config, server_cfengine_policy);
    if (thislock.lock == NULL)
    {
        PolicyDestroy(server_cfengine_policy);
        if (sd >= 0)
        {
            cf_closesocket(sd);
        }
        return -1;
    }

    PrepareServer(sd);
    CollectCallStart(COLLECT_INTERVAL);

    while (!IsPendingTermination())
    {
        CollectCallIfDue(ctx);

        int selected = WaitForIncoming(sd);

        Log(LOG_LEVEL_DEBUG, "select(): %d", selected);
        if (selected == -1)
        {
            Log(LOG_LEVEL_ERR,
                "Error while waiting for connections. (select: %s)",
                GetErrorStr());
            break;
        }
        else if (selected >= 0) /* timeout or success */
        {
            PolicyUpdateIfSafe(ctx, policy, config);

            /* Is there a new connection pending at our listening socket? */
            if (selected > 0)
            {
                AcceptAndHandle(ctx, sd);
            }
        } /* else: interrupted, maybe pending termination. */
    }
    Log(LOG_LEVEL_NOTICE, "Cleaning up and exiting...");

    CollectCallStop();
    if (sd != -1)
    {
        Log(LOG_LEVEL_VERBOSE, "Closing listening socket");
        cf_closesocket(sd);                       /* Close listening socket */
    }

    /* This is a graceful exit, give 2 seconds chance to threads. */
    int threads_left = WaitOnThreads();
    YieldCurrentLock(thislock);
    PolicyDestroy(server_cfengine_policy);

    return threads_left;
}