Пример #1
0
void cli_local_main( void* pport ) {
    uint16_t port;
    struct sockaddr_in addr;
    struct sockaddr client_addr;
    unsigned sock_len = sizeof(struct sockaddr);
    int bindfd;
    int clientfd;
    cli_client_t* client;

    port = *(uint16_t*)pport;
    free( pport );

    /* create a socket to listen for connections on */
    bindfd = socket( AF_INET, SOCK_STREAM, 0 );
    if( bindfd == -1 ) {
        die( "Error: unable to create a real IPv4 TCP socket" );
    }

    /* allow reuse of the port */
    int reuse = 1;
    if( setsockopt( bindfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse) ) )
        die( "Error: SO_REUSEADDR failed" );

    /* bind to the requested port */
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = 0;
    memset(&(addr.sin_zero), 0, sizeof(addr.sin_zero));
    if( bind(bindfd, (struct sockaddr*)&addr, sizeof(struct sockaddr)) ) {
        die( "Error: unable to bind to local port %u", port );
    }

    /* listen for clients */
    listen( bindfd, 10 );

    while( !cli_is_time_to_shutdown() ) {
        /* wait for a new client */
        clientfd = accept(bindfd, &client_addr, &sock_len);
        if( clientfd == - 1 ) {
            if( errno == EINTR ) {
                /* Interrupt received, going back to real accept() */
                continue;
            }

            /* some error */
            fprintf( stderr, "Warrning: real accept() returned an error code (%d)", errno );
            continue;
        }

        /* create a client record */
        client = (cli_client_t*)malloc_or_die( sizeof(cli_client_t) );
        client->fd = -clientfd; /* negative means use the real sockets */
        search_state_init( &client->state, CLI_INIT_BUF, CLI_MAX_BUF );

        /* spawn a new thread to handle the client */
        sys_thread_new( cli_client_handler_main, client );
    }

    exit( 0 );
}
Пример #2
0
/**
 * Detaches and then handles pclient exclusively.  If pclient sends a shutdown
 * message, then the thread shuts down the whole router.  If pclient quits, then
 * the thread terminates after cleaning up.
 */
THREAD_RETURN_TYPE cli_client_handler_main( void* pclient ) {
    cli_client_t* client;

    client = (cli_client_t*)pclient;
    client->verbose = 0;
    pthread_detach( pthread_self() );

    /* ignore the broken pipe signal */
    signal( SIGPIPE, SIG_IGN );

    /* first read always pulls crap data from socket for some reason, so just
       get it now */
    cli_client_handle_request( client );
    client->state.used = client->state.search_offset = client->state.needle_offset = 0;

    /* welcome the client */
    pthread_mutex_lock( &parser_lock );
    cli_focus_set( client->fd, &client->verbose );
    cli_send_welcome();
    cli_send_prompt();
    pthread_mutex_unlock( &parser_lock );

    while( 1 ) {
        int res = cli_client_handle_request( client );

        /* if the client shutdown the router, bail now */
        if( cli_is_time_to_shutdown() ) {
            exit( 1 );
        }

        /* cleanup the client's memory & terminate this thread if client quit */
        if( !res ) {
            cli_client_cleanup( client );
            free( client );
            THREAD_RETURN_NIL;
        }
    }
}
Пример #3
0
int cli_main( uint16_t port ) {
    struct sockaddr_in addr;
    struct sockaddr client_addr;
    int bindfd;
    int clientfd;
    cli_client_t* client;
#ifdef _STANDALONE_CLI_
    unsigned sock_len;
#else
    int sock_len;
#endif

    sock_len = sizeof(struct sockaddr);
    pthread_mutex_init( &parser_lock, NULL );

    cli_init();
    cli_parser_init();
    cli_scanner_init();

    /* create a socket to listen for connections on */
    bindfd = socket( AF_INET, SOCK_STREAM, 0 );
    if( bindfd == -1 ) {
        fprintf( stderr, "Error: unable to create a IPv4 TCP socket" );
        return CLI_ERROR;
    }

    /* bind to the requested port */
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = 0;
    memset(&(addr.sin_zero), 0, sizeof(addr.sin_zero));
    if( bind(bindfd, (struct sockaddr*)&addr, sizeof(struct sockaddr)) ) {
        fprintf( stderr, "Error: CLI unable to bind to port %u", port );
        return CLI_ERROR;
    }

    /* listen for clients */
    listen( bindfd, 10 );

#ifndef _STANDALONE_CLI_
    /* listen locally too */
    cli_local_init( port );
#endif

    while( !cli_is_time_to_shutdown() ) {
        /* wait for a new client */
        clientfd = accept(bindfd, &client_addr, &sock_len);
        if( clientfd == - 1 ) {
            if( errno == EINTR ) {
                /* Interrupt received, going back to accept() */
                continue;
            }

            /* some error */
            perror( "accept() failed" );
            continue;
        }
        /* accepted a new connection client */

        /* create a client record */
        client = malloc_or_die( sizeof(cli_client_t) );
        client->fd = clientfd;
        search_state_init( &client->state, CLI_INIT_BUF, CLI_MAX_BUF );

        /* spawn a new thread to handle the client */
        make_thread( cli_client_handler_main, client );
    }

    return CLI_SHUTDOWN;
}