Example #1
0
/*
 * Test the network write function with a timeout.  We fork off a child
 * process that runs delay_reader, and then we write 64KB to the network in
 * two chunks, once with a timeout and once without, and then try a third time
 * when we should time out.
 */
static void
test_network_write(void)
{
    socket_type fd, c;
    pid_t child;
    struct sockaddr_in sin;
    socklen_t slen;
    char *buffer;

    /* Create the data that we're going to send. */
    buffer = bmalloc(4096 * 1024);
    memset(buffer, 'a', 4096 * 1024);

    /* Create the listening socket. */
    fd = network_bind_ipv4(SOCK_STREAM, "127.0.0.1", 11119);
    if (fd == INVALID_SOCKET)
        sysbail("cannot create or bind socket");
    if (listen(fd, 1) < 0)
        sysbail("cannot listen to socket");

    /* Create the child, which will connect and then read data with delay. */
    child = fork();
    if (child < 0)
        sysbail("cannot fork");
    else if (child == 0) {
        socket_close(fd);
        client_delay_reader("127.0.0.1");
    }

    /* Set an alarm just in case our timeouts don't work. */
    alarm(10);

    /* Accept the client connection. */
    slen = sizeof(struct sockaddr_in);
    c = accept(fd, &sin, &slen);
    if (c == INVALID_SOCKET)
        sysbail("cannot accept on socket");

    /* Test some successful writes with and without a timeout. */
    socket_set_errno(0);
    ok(network_write(c, buffer, 32 * 1024, 0), "network_write");
    ok(network_write(c, buffer, 32 * 1024, 1),
       "network_write with timeout");

    /*
     * A longer write cannot be completely absorbed before the client sleep,
     * so should fail with a timeout.
     */
    ok(!network_write(c, buffer, 4096 * 1024, 1),
       "network_write aborted with timeout");
    is_int(ETIMEDOUT, socket_errno, "...with correct error");
    alarm(0);

    /* Clean up. */
    socket_close(c);
    kill(child, SIGTERM);
    waitpid(child, NULL, 0);
    socket_close(fd);
    free(buffer);
}
Example #2
0
ssize_t recv(int sock, void * p_buf, size_t buf_size, int flags)
{
    VERIFY_MODULE_IS_INITIALIZED();
    VERIFY_SOCKET_ID(sock);
    NULL_PARAM_CHECK(p_buf);

    SOCKET_MUTEX_LOCK();
    socket_entry_t * p_socket_entry = &m_socket_table[sock];
    SOCKET_MUTEX_UNLOCK();

    ssize_t ret = -1;
    if (p_socket_entry->state == STATE_CONNECTED)
    {
        uint32_t recv_size = 0;
        uint32_t err_code = socket_recv(&p_socket_entry->handle,
                                        p_buf,
                                        buf_size,
                                        &recv_size,
                                        flags);
        if (err_code == NRF_SUCCESS)
        {
            ret = (ssize_t) recv_size;
        }
        socket_set_errno(err_code);
    }
    else
    {
        set_errno(ENOTCONN);
    }
    return ret;
}
Example #3
0
int
connect(int sock, const void * p_addr, socklen_t addrlen)
{
    VERIFY_MODULE_IS_INITIALIZED();
    VERIFY_SOCKET_ID(sock);
    NULL_PARAM_CHECK(p_addr);

    SOCKET_MUTEX_LOCK();
    socket_entry_t * p_socket_entry = &m_socket_table[sock];
    SOCKET_MUTEX_UNLOCK();

    int ret = -1;
    if (p_socket_entry->state == STATE_OPEN)
    {
        uint32_t err_code = p_socket_entry->handler->connect_handler(&p_socket_entry->handle,
                                                                     p_addr,
                                                                     addrlen);
        if (err_code == NRF_SUCCESS)
        {
            p_socket_entry->state = STATE_CONNECTED;
            ret = 0;
        }
        socket_set_errno(err_code);
    }
    else if (p_socket_entry->state == STATE_CONNECTED)
    {
        set_errno(EISCONN);
    }
    else if (p_socket_entry->state == STATE_CLOSED)
    {
        set_errno(EBADF);
    }
    return ret;
}
Example #4
0
/*
 * Receive a token from a file descriptor.  Takes the file descriptor, a
 * buffer into which to store the token, a pointer into which to store the
 * flags, and the maximum token length we're willing to accept.  Returns
 * TOKEN_OK on success.  On failure, returns one of:
 *
 *     TOKEN_FAIL_SYSTEM       System call failed, errno set
 *     TOKEN_FAIL_SOCKET       Socket call failed, socket_errno set
 *     TOKEN_FAIL_INVALID      Invalid token format
 *     TOKEN_FAIL_LARGE        Token data larger than provided limit
 *     TOKEN_FAIL_EOF          Unexpected end of file
 *     TOKEN_FAIL_TIMEOUT      Timeout receiving token
 *
 * TOKEN_FAIL_SYSTEM and TOKEN_FAIL_SOCKET are the same on UNIX but different
 * on Windows.
 *
 * recv_token reads the token flags (a single byte, even though they're stored
 * into an integer, then reads the token length (as a network long), allocates
 * memory to hold the data, and then reads the token data from the file
 * descriptor.  On a successful return, the value member of the token should
 * be freed with free().
 */
enum token_status
token_recv(socket_type fd, int *flags, gss_buffer_t tok, size_t max,
           time_t timeout)
{
    OM_uint32 len;
    unsigned char char_flags;
    int err;

    if (!network_read(fd, &char_flags, 1, timeout))
        return map_socket_error(socket_errno);
    *flags = char_flags;

    if (!network_read(fd, &len, sizeof(OM_uint32), timeout))
        return map_socket_error(socket_errno);
    tok->length = ntohl(len);
    if (tok->length > max)
        return TOKEN_FAIL_LARGE;
    if (tok->length == 0) {
        tok->value = NULL;
        return TOKEN_OK;
    }

    tok->value = malloc(tok->length);
    if (tok->value == NULL)
        return TOKEN_FAIL_SYSTEM;
    if (!network_read(fd, tok->value, tok->length, timeout)) {
        err = socket_errno;
        free(tok->value);
        socket_set_errno(err);
        return map_socket_error(err);
    }
    return TOKEN_OK;
}
Example #5
0
/*
 * Test the network read function with a timeout.  We fork off a child process
 * that runs delay_writer, and then we read from the network twice, once with
 * a timeout and once without, and then try a third time when we should time
 * out.
 */
static void
test_network_read(void)
{
    socket_type fd, c;
    pid_t child;
    struct sockaddr_in sin;
    socklen_t slen;
    char buffer[4];

    /* Create the listening socket. */
    fd = network_bind_ipv4(SOCK_STREAM, "127.0.0.1", 11119);
    if (fd == INVALID_SOCKET)
        sysbail("cannot create or bind socket");
    if (listen(fd, 1) < 0)
        sysbail("cannot listen to socket");

    /* Fork off a child process that writes some data with delays. */
    child = fork();
    if (child < 0)
        sysbail("cannot fork");
    else if (child == 0) {
        socket_close(fd);
        client_delay_writer("127.0.0.1");
    }

    /* Set an alarm just in case our timeouts don't work. */
    alarm(10);

    /* Accept the client connection. */
    slen = sizeof(sin);
    c = accept(fd, &sin, &slen);
    if (c == INVALID_SOCKET)
        sysbail("cannot accept on socket");

    /* Now test a couple of simple reads, with and without timeout. */
    socket_set_errno(0);
    ok(network_read(c, buffer, sizeof(buffer), 0), "network_read");
    ok(memcmp("one\n", buffer, sizeof(buffer)) == 0, "...with good data");
    ok(network_read(c, buffer, sizeof(buffer), 1),
       "network_read with timeout");
    ok(memcmp("two\n", buffer, sizeof(buffer)) == 0, "...with good data");

    /*
     * The third read should abort with a timeout, since the writer is writing
     * with a ten second delay.
     */
    ok(!network_read(c, buffer, sizeof(buffer), 1),
       "network_read aborted with timeout");
    is_int(ETIMEDOUT, socket_errno, "...with correct error");
    ok(memcmp("two\n", buffer, sizeof(buffer)) == 0, "...and data unchanged");
    alarm(0);

    /* Clean up. */
    socket_close(c);
    kill(child, SIGTERM);
    waitpid(child, NULL, 0);
    socket_close(fd);
}
Example #6
0
int
socket(socket_family_t family, socket_type_t type, socket_protocol_t protocol)
{
    if (m_initialization_state == false)
    {
        (void) socket_init();
    }
    VERIFY_MODULE_IS_INITIALIZED();

    int ret_sock = -1;
    int sock = socket_allocate();
    SOCKET_TRACE("Got value %d from allocate\r\n", (int)sock);
    if (sock >= 0)
    {
        socket_entry_t *p_socket_entry = &m_socket_table[sock];
        p_socket_entry->handle.params.family = family;
        p_socket_entry->handle.params.protocol = protocol;
        p_socket_entry->handle.params.type = type;
        p_socket_entry->handler = NULL;

        if (family == AF_INET6)
        {
#if SOCKET_IPV6_ENABLE == 1 || SOCKET_LWIP_ENABLE == 1
            p_socket_entry->handler = &transport_handler;
#else
            set_errno(EAFNOSUPPORT);
#endif
        // } else if (family == AF_BLE) {
            // TODO: Handle BLE
        }
        else
        {
            set_errno(EAFNOSUPPORT);
        }

        if (p_socket_entry->handler != NULL)
        {
            uint32_t err_code = p_socket_entry->handler->create_handler(&p_socket_entry->handle);
            socket_set_errno(err_code);
            ret_sock = (err_code == NRF_SUCCESS) ? sock : ret_sock;
        }

        if (ret_sock < 0)
        {
            socket_free(sock);
        }
    }
    SOCKET_TRACE("Returning socket value %d\r\n", (int)ret_sock);
    return ret_sock;
}