예제 #1
0
/*----------------------------------------------------------------------------*/
udps_err_t udps_accept(void)
{
    pid_t      pid;
    udps_err_t rc;

    /* Initialize processes controller. */
    LOG_SRV(UDPS_LOG_DEBUG, ("Initializing processes controller..."));
    rc = udps_lock_init();
    if(rc != UDPS_OK) {
        LOG_SRV(UDPS_LOG_EMERG, ("Could not initialize processes "
                                 "controller"));
        udps_close();
        return rc;
    }

    /* Initialize message queue. */
    LOG_SRV(UDPS_LOG_DEBUG, ("Initializing message queue..."));
    rc = udps_mq_init();
    if(rc != UDPS_OK) {
        LOG_SRV(UDPS_LOG_EMERG, ("Could not initialize message queue"));
        udps_close();
        return rc;
    }

    /* Initialize processes pool. */
    LOG_SRV(UDPS_LOG_DEBUG, ("Initializing processes pool..."));
    rc = udps_pool_init(srv.nclients, udps_client_handler);
    if(rc != UDPS_OK) {
        LOG_SRV(UDPS_LOG_EMERG, ("Could not initialize processes pool"));
        udps_close();
        return rc;
    }

    /* Launch Receiver and PoolUpdater processes. */
    pid = fork();
    if(pid > 0) { /* Parent. */
        srv.pUpdater = 0;
        rc = udps_receive();
    } else if(pid == 0) { /* Child. */
        srv.pUpdater = 1;
        for(;;) {
            sleep(1);
            rc = udps_pool_update();
            if(rc != UDPS_OK) {
                LOG_SRV(UDPS_LOG_ALERT, ("Unable to update processes pool"));
            }
        }
    } else {
        LOG_POOL(UDPS_LOG_CRIT, ("Unable to fork Receiver/PoolUpdater"
                                 "processes"));
        return UDPS_ERR_FORK;
    }

    return UDPS_OK;
}
예제 #2
0
파일: udps.c 프로젝트: alexeyk13/rexos
void udps_request(TCPIPS* tcpips, IPC* ipc)
{
    if (!tcpips->connected)
    {
        error(ERROR_NOT_ACTIVE);
        return;
    }
    switch (HAL_ITEM(ipc->cmd))
    {
    case IPC_OPEN:
        if (ipc->param2 == LOCALHOST)
            udps_listen(tcpips, ipc);
        else
            udps_connect(tcpips, ipc);
        break;
    case IPC_CLOSE:
        udps_close(tcpips, ipc->param1);
        break;
    case IPC_READ:
        udps_read(tcpips, ipc->param1, (IO*)ipc->param2);
        break;
    case IPC_WRITE:
        udps_write(tcpips, ipc->param1, (IO*)ipc->param2);
        break;
    case IPC_FLUSH:
        udps_flush(tcpips, ipc->param1);
        break;
    default:
        error(ERROR_NOT_SUPPORTED);
    }
}
예제 #3
0
/**
 * Handle SIGINT signal.
 * @param[in] signo
 */
static void udps_signal_handler(int signo)
{
    (void)signo;
    LOG_MAIN(UDPS_LOG_NOTICE, ("Signal received: %s (%d). Closing UDP server",
                               strsignal(signo), signo));
    udps_close();
    exit(EXIT_SUCCESS);
}
예제 #4
0
/*----------------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
    ushort     port;
    uchar      nclients;
    udps_err_t rc;

    /* Check server initialization arguments. */
    if(argc != 3) {
        udps_print_usage(argv[0]);
    }

    /* Load configuration. */
    port     = atoi(argv[1]);
    nclients = atoi(argv[2]);

    /* Handle signals.
     * SIGINT  = When the user types the INTR character (normally C-c).
     * SIGTERM = Generic signal used to cause program termination. */
    signal(SIGINT, udps_signal_handler);
    signal(SIGTERM, NULL);

    /* Initialize. */
    rc = udps_init(port, nclients);
    if(rc != UDPS_OK) {
        LOG_MAIN(UDPS_LOG_EMERG, ("Unable to initialize  UDP server"));
        exit(EXIT_FAILURE);
    }

    /* Accept. */
    rc = udps_accept();
    if(rc != UDPS_OK) {
        LOG_MAIN(UDPS_LOG_EMERG, ("Unable to start accepting"));
        exit(EXIT_FAILURE);
    }

    /* Close. */
    udps_close();

    return EXIT_SUCCESS;
}
예제 #5
0
/*----------------------------------------------------------------------------*/
udps_err_t udps_init(ushort port, uchar nclients)
{
    struct sockaddr_in srvaddr;
    socklen_t          srvlen;
    int                reuse;
    struct rlimit      rlp;

    /* Setup internal configurations. */
    memset(&srv, 0, sizeof(srv));
    srv.port     = port;
    srv.nclients = nclients;

    /* Setup file limits. */
    if(getrlimit(RLIMIT_NOFILE, &rlp) != 0) {
        LOG_SRV(UDPS_LOG_EMERG, ("Could not get RLIMIT_NOFILE: %s (%d)",
                                 strerror(errno), errno));
        return UDPS_ERR_GET_RLIMIT;
    }
    rlp.rlim_cur = UDPS_RLIMIT_NOFILE;
    if(setrlimit(RLIMIT_NOFILE, &rlp) != 0) {
        LOG_SRV(UDPS_LOG_EMERG, ("Could not set RLIMIT_NOFILE: %s (%d)",
                                 strerror(errno), errno));
        return UDPS_ERR_SET_RLIMIT;
    }

    /* Create UDP communication endpoint.
     * AF_INET     = Internet domain sockets.
     * SOCK_STREAM = Byte-stream socket. */
    LOG_SRV(UDPS_LOG_DEBUG, ("Creating UDP socket..."));
    srv.udpfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(srv.udpfd < 0) {
        LOG_SRV(UDPS_LOG_EMERG, ("Unable to create UDP communication endpoint: "
                                 "%s (%d)", strerror(errno), errno));
        return UDPS_ERR_CREATE_UDP_SOCKET;
    }
    LOG_SRV(UDPS_LOG_DEBUG, ("UDP socket created: %d", srv.udpfd));

    /* Create server address.
     * INADDR_ANY = the socket will be bound to all local interfaces. */
    memset(&srvaddr, 0, sizeof(srvaddr));
    srvaddr.sin_family      = AF_INET;
    srvaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    srvaddr.sin_port        = htons(srv.port);

    /* Allow reuse of local addresses.
     * SOL_SOCKET   = Manipulate the socket-level options.
     * SO_REUSEADDR = Indicates that the rules used in validating addresses
     *                supplied in a bind() call should allow reuse of local
     *                addresses. */
    reuse = 1;
    if(setsockopt(srv.udpfd, SOL_SOCKET, SO_REUSEADDR, &reuse,
                  sizeof(reuse)) != 0) {
        LOG_SRV(UDPS_LOG_EMERG, ("Unable to set address as reusable: %s (%d)",
                                 strerror(errno), errno));
        return UDPS_ERR_SET_ADDR_REUSABLE;
    }

    /* Bind UDP endpoint to server address. */
    LOG_SRV(UDPS_LOG_DEBUG, ("Binding UDP socket..."));
    if(bind(srv.udpfd, (struct sockaddr*)&srvaddr, sizeof(srvaddr)) < 0) {
        LOG_SRV(UDPS_LOG_EMERG, ("Unable to bind server socket with its "
                                 "address: %s (%d)", strerror(errno), errno));
        udps_close();
        return UDPS_ERR_BIND_UDP_SOCKET;
    }

    /* Check sockname. */
    LOG_SRV(UDPS_LOG_DEBUG, ("Checking sockname..."));
    srvlen = sizeof(srvaddr);
    if((getsockname(srv.udpfd, (struct sockaddr*)&srvaddr, &srvlen) < 0) ||
       (srvlen != sizeof(srvaddr))) {
        LOG_SRV(UDPS_LOG_EMERG, ("Invalid server socket address length: "
                                 "%u != %lu", srvlen, sizeof(srvaddr)));
        udps_close();
        return UDPS_ERR_INVALID_UDP_SOCKET;
    }

    /* Check address family. */
    LOG_SRV(UDPS_LOG_DEBUG, ("Checking address family..."));
    if(srvaddr.sin_family != AF_INET) {
        LOG_SRV(UDPS_LOG_EMERG, ("Invalid server socket family: != AF_INET"));
        udps_close();
        return UDPS_ERR_INVALID_UDP_SOCKET;
    }

    /* Initialize. */
    LOG_SRV(UDPS_LOG_NOTICE, ("Init UDP => udpServer.udpfd: %d "
                              "- port: %u", srv.udpfd, srv.port));

    return UDPS_OK;
}