Esempio n. 1
0
/*
 *===========================================================================
 *                    ipcom_cmd_sockperf_connect
 *===========================================================================
 * Description: Active open of socket(s)
 * Parameters:
 * Returns:
 */
IP_STATIC void
ipcom_cmd_sockperf_connect(Ipcom_cmd_sockperf_t *cmd)
{
    Ip_fd            *s = cmd->sock_array;
    Ip_u32            created_sockets;
    struct Ip_timeval start;
    struct Ip_timeval stop;

    ipcom_printf("sockperf-c: connecting to %s[%d]"IP_LF,
                 cmd->res->ai_canonname,
                 ip_ntohs(((struct Ip_sockaddr_in *)cmd->res->ai_addr)->sin_port));
    ipcom_microtime(&start);
    for (created_sockets = 0; created_sockets < cmd->num_sock; created_sockets++)
    {
        s[created_sockets] = ipcom_socket(cmd->res->ai_family,
                                          cmd->res->ai_socktype,
                                          cmd->res->ai_protocol);
        if (s[created_sockets] == IP_SOCKERR)
        {
            ipcom_printf("sockperf-c: Failed to create socket: %s"IP_LF,
                         ipcom_strerror(ipcom_errno));
            created_sockets--;
            goto cleanup;
        }

        if (ipcom_setsockopt(s[created_sockets],
                             IP_SOL_SOCKET,
                             IP_SO_LINGER,
                             &cmd->linger,
                             sizeof(cmd->linger)) < 0)
        {
            ipcom_printf("sockperf-c: setsockopt SO_LINGER failed : %s"IP_LF,
                         ipcom_strerror(ipcom_errno));
            goto cleanup;
        }

        if (ipcom_connect(s[created_sockets], cmd->res->ai_addr, cmd->res->ai_addrlen) < 0)
        {
            ipcom_printf("sockperf-c: Failed to connect: %s"IP_LF,
                         ipcom_strerror(ipcom_errno));
            goto cleanup;
        }
    }
    ipcom_microtime(&stop);
    ipcom_printf("sockperf-t: %ld sockets connected in %ld ms"IP_LF,
                 created_sockets,
                 ipcom_cmd_sockperf_tv_to_msec(&start, &stop));

    ipcom_cmd_sockperf_run(cmd);

 cleanup:
    while (created_sockets > 0)
        (void)ipcom_socketclose(s[created_sockets--]);
}
/*
 *===========================================================================
 *                    ipcom_waitif
 *===========================================================================
 * Description: Wait for interface to get an IP address assigned.
 * Parameters:  ifindex - Index of the interface to wait for.
 *                        0 = any interface except loopback.
 *              domain - The address domain.
 * Returns:     0 = success, -1 = error, and sets errno.
 *
 */
IP_PUBLIC int
ipcom_waitif(int ifindex, int domain)
{
    struct Ipnet_rs_msghdr rtmsg;
    struct Ip_timeval stop;
    struct Ip_timeval tv;
    Ip_fd fd = IP_INVALID_SOCKET;
    int ret = -1;

    /* Check domain */
    if (domain != IP_AF_INET
#ifdef IPCOM_USE_INET6
        && domain != IP_AF_INET6
#endif /* IPCOM_USE_INET6 */
       )
    {
        IPCOM_LOG1(ERR, "ipcom_waitif :: invalid domain: %d", domain);
        ipcom_errno_set(IP_ERRNO_EINVAL);
        goto leave;
    }

    /* Get routing socket */
    fd = ipcom_socket(IP_AF_ROUTE, IP_SOCK_RAW, 0);
    if (fd == IP_INVALID_SOCKET)
    {
        IPCOM_LOG1(ERR, "ipcom_waitif :: ipcom_socket(ROUTE, RAW) failed, errno = %d", ipcom_errno);
        goto leave;
    }

    /* Get stop time */
    ipcom_microtime(&tv);
    stop.tv_sec = tv.tv_sec + IPNET_WAITIF_TIMEOUT;

    /* Loop and wait for address */
    for (;;)
    {
        Ip_ssize_t length;

        /* Check if address available */
        if (ifindex == 0)
        {
            int i;

            /* Any if will do */
            for (i = 2; i < IPNET_WAITIF_MAXIF; i++)
            {
                if (ipcom_waitif_gifaddr(fd, i, domain) == 0)
                {
                    ret = 0;
                    goto leave;
                }
            }
        }
        else if (ipcom_waitif_gifaddr(fd, ifindex, domain) == 0)
        {
            ret = 0;
            goto leave;
        }

again:
        /* Get timeout time */
        ipcom_microtime(&tv);
        tv.tv_sec = stop.tv_sec - tv.tv_sec;
        tv.tv_usec = 0;
        if (tv.tv_sec <= 0)
        {
            ipcom_errno_set(IP_ERRNO_ETIMEDOUT);
            goto leave;
        }

        /* Set receive timeout */
        if (ipcom_setsockopt(fd, IP_SOL_SOCKET, IP_SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
        {
            IPCOM_LOG1(ERR, "ipcom_waitif :: ipcom_setsockopt(RCVTIMEO) failed, errno = %d", ipcom_errno);
            goto leave;
        }

        /* Read routing message headers only (truncated read). */
        length = ipcom_recv(fd, &rtmsg, sizeof(rtmsg), 0);
        if (length == IP_SOCKERR)
        {
            if (ipcom_errno != IP_ERRNO_ETIMEDOUT && ipcom_errno != IP_ERRNO_EWOULDBLOCK)
            {
                IPCOM_LOG1(ERR, "ipcom_waitif :: ipcom_recv() failed, errno = %d", ipcom_errno);
            }

            goto leave;
        }

        /* Only bother about newaddr */
        if (rtmsg.type != IPNET_RTM_NEWADDR)
        {
            goto again;
        }
    }

leave:
    if (fd != IP_INVALID_SOCKET)
    {
        ipcom_socketclose(fd);
    }

    return ret;
}
Esempio n. 3
0
/*
 *===========================================================================
 *                    ipcom_cmd_sockperf_accept
 *===========================================================================
 * Description: Passive open of socket(s).
 * Parameters:
 * Returns:
 */
IP_STATIC void
ipcom_cmd_sockperf_accept(Ipcom_cmd_sockperf_t *cmd)
{
    Ip_fd            *s = cmd->sock_array;
    int               listen_sock;
    Ip_u32            accepted_sockets = 0;
    struct Ip_timeval start;
    struct Ip_timeval stop;
    int               on = 1;

    listen_sock = ipcom_socket(cmd->res->ai_family,
                               cmd->res->ai_socktype,
                               cmd->res->ai_protocol);

    if (listen_sock == IP_SOCKERR)
    {
        ipcom_printf("sockperf-a: Failed to create socket: %s"IP_LF,
                     ipcom_strerror(ipcom_errno));
        goto cleanup;
    }


    if (ipcom_setsockopt(listen_sock,
                         IP_SOL_SOCKET,
                         IP_SO_REUSEADDR,
                         &on,
                         sizeof(on)) < 0)
    {
        ipcom_printf("sockperf-a: setsockopt IP_SO_REUSEADDR failed : %s"IP_LF,
                     ipcom_strerror(ipcom_errno));
        return;
    }

    if (ipcom_bind(listen_sock, cmd->res->ai_addr, cmd->res->ai_addrlen) < 0)
    {
        ipcom_printf("sockperf-a: Failed to bind: %s"IP_LF,
                     ipcom_strerror(ipcom_errno));
        goto cleanup;
    }

    if (ipcom_listen(listen_sock, cmd->num_sock) < 0)
    {
        ipcom_printf("sockperf-a: Failed to listen: %s"IP_LF,
                     ipcom_strerror(ipcom_errno));
        goto cleanup;
    }

    ipcom_printf("sockperf-a: listen on %s[%d]"IP_LF,
                 cmd->res->ai_canonname,
                 ip_ntohs(((struct Ip_sockaddr_in *)cmd->res->ai_addr)->sin_port));

    IP_FD_ZERO(&cmd->read_set);
    IP_FD_SET(listen_sock, &cmd->read_set);
    if (ipcom_socketselect(listen_sock + 1, &cmd->read_set, IP_NULL, IP_NULL, IP_NULL) != 1)
    {
        ipcom_printf("sockperf-a: Select failed for listen socket: %s"IP_LF,
                     ipcom_strerror(ipcom_errno));
        goto cleanup;
    }

    ipcom_microtime(&start);
    for (;accepted_sockets < cmd->num_sock; accepted_sockets++)
    {
        s[accepted_sockets] = ipcom_accept(listen_sock, IP_NULL, IP_NULL);
        if (s[accepted_sockets] == IP_SOCKERR)
        {
            ipcom_printf("sockperf-a: Failed to create socket: %s"IP_LF,
                     ipcom_strerror(ipcom_errno));
            goto cleanup;
        }
        if (ipcom_setsockopt(s[accepted_sockets],
                             IP_SOL_SOCKET,
                             IP_SO_LINGER,
                             &cmd->linger,
                             sizeof(cmd->linger)) < 0)
        {
            ipcom_printf("sockperf-a: setsockopt SO_LINGER failed : %s"IP_LF,
                         ipcom_strerror(ipcom_errno));
            goto cleanup;
        }
    }
    ipcom_microtime(&stop);
    ipcom_printf("sockperf-a: %ld sockets accepted in %ld ms"IP_LF,
                 accepted_sockets,
                 ipcom_cmd_sockperf_tv_to_msec(&start, &stop));

    ipcom_cmd_sockperf_run(cmd);

 cleanup:
    if (listen_sock >= 0)
        (void)ipcom_socketclose(listen_sock);
    while (accepted_sockets-- > 0)
        (void)ipcom_socketclose(s[accepted_sockets]);
}
Esempio n. 4
0
/*
 *===========================================================================
 *                    ipcom_cmd_sockperf_run
 *===========================================================================
 * Description: Sends/receives data.
 * Parameters:
 * Returns:
 */
IP_STATIC void
ipcom_cmd_sockperf_run(Ipcom_cmd_sockperf_t *cmd)
{
    struct Ip_timeval  tmo = { 0, 0 };
    struct Ip_timeval *ptmo;
    struct Ip_timeval  start;
    struct Ip_timeval  stop;
    Ip_u32             i;
    Ip_u32             c;
    int                num_ready;
    Ip_fd             *s = cmd->sock_array;
    Ip_u32             total_bytes_to_send = cmd->num_buf * cmd->buf_len;
    Ip_u32             finished_sockets = 0;
    Ip_u32             total_bytes_read = 0;
    Ip_ssize_t         bytes;
    Ip_fd_set          read_set;
    int                send_flags = (cmd->transmit && cmd->receive) ? IP_MSG_DONTWAIT : 0;

    if (cmd->transmit)
        ipcom_printf("sockperf-t: send buffer is %u"IP_LF, cmd->sendbuf_size);
    if (cmd->receive)
        ipcom_printf("sockperf-r: receive buffer is %u"IP_LF, cmd->sendbuf_size);
    for (i = 0; i < cmd->num_sock; i++)
    {
        int on = 1;

        if (ipcom_setsockopt(s[i],
                             IP_SOL_SOCKET,
                             IP_SO_REUSEADDR,
                             &on,
                             sizeof(on)) < 0)
        {
            ipcom_printf("sockperf-c: setsockopt IP_SO_REUSEADDR failed : %s"IP_LF,
                         ipcom_strerror(ipcom_errno));
            return;
        }

        if (ipcom_setsockopt(s[i],
                             IP_SOL_SOCKET,
                             IP_SO_SNDBUF,
                             &cmd->sendbuf_size,
                             sizeof(cmd->sendbuf_size)) < 0)
        {
            ipcom_printf("sockperf-c: setsockopt IP_SO_SNDBUF failed : %s"IP_LF,
                         ipcom_strerror(ipcom_errno));
            return;
        }

        if (ipcom_setsockopt(s[i],
                             IP_SOL_SOCKET,
                             IP_SO_RCVBUF,
                             &cmd->recvbuf_size,
                             sizeof(cmd->recvbuf_size)) < 0)
        {
            ipcom_printf("sockperf-c: setsockopt IP_SO_SNDBUF failed : %s"IP_LF,
                         ipcom_strerror(ipcom_errno));
            return;
        }
    }


    if (cmd->receive)
    {
        IP_FD_ZERO(&cmd->read_set);
        cmd->width = s[0];
        IP_FD_SET(s[0], &cmd->read_set);
        for (i = 1; i < cmd->num_sock; i++)
            if (s[i] != IP_INVALID_SOCKET)
            {
                cmd->width = IP_MAX(cmd->width, s[i]);
                IP_FD_SET(s[i], &cmd->read_set);
            }
    }

    ipcom_microtime(&start);
    while ((cmd->transmit && total_bytes_to_send)
           || (cmd->receive && finished_sockets < cmd->num_sock))
    {
        if (cmd->transmit && total_bytes_to_send)
        {
            for (i = 0; i < cmd->num_sock; i++)
            {
                if (cmd->testpattern)
                {
                    /* Test patter is "[B|E|D]xxxxxx ", B = first 8 byte in buffer, E = last 8 bytes, D = all other */
                    for (c = 0; c < cmd->buf_len; c += 8)
                        ipcom_sprintf(cmd->buf + c, "%c%06ld ",
                                      c == 0 ? '>' : (c >= cmd->buf_len - 8 ? '<' : '#'),
                                      cmd->send_pattern[i]++ % 1000000);
                }

                bytes = ipcom_send(s[i],
                                   cmd->buf,
                                   IP_MIN(cmd->buf_len, total_bytes_to_send),
                                   send_flags);
                if (bytes < 0 && ipcom_errno == IP_ERRNO_EWOULDBLOCK)
                    (void)ipcom_sleep(0);
                else
                {
                    if (bytes < 0)
                    {
                        ipcom_printf("sockperf-t: send failed : %s"IP_LF,
                                     ipcom_strerror(ipcom_errno));
                        return;
                    }
                    total_bytes_to_send -= bytes;
                }
            }

            if (cmd->receive && total_bytes_to_send == 0)
                for (i = 0; i < cmd->num_sock; i++)
                    if (ipcom_shutdown(s[i], IP_SHUT_WR) < 0)
                    {
                        ipcom_printf("sockperf-t: shutdown failed: %s"IP_LF,
                                     ipcom_strerror(ipcom_errno));
                        return;
                    }
        }

        if (cmd->receive)
        {
            ptmo = IP_NULL;
            while (finished_sockets < cmd->num_sock)
            {
                read_set = cmd->read_set;
                num_ready = ipcom_socketselect(cmd->width + 1, &read_set, IP_NULL, IP_NULL, ptmo);

                if (num_ready == 0)
                    break;

                if (num_ready < 0)
                {
                    ipcom_printf("sockperf-r: select failed: %s"IP_LF,
                                 ipcom_strerror(ipcom_errno));
                    return;
                }

                for (i = 0; i < cmd->num_sock; i++)
                {
                    if (IP_FD_ISSET(s[i], &read_set))
                    {
                        bytes = ipcom_recv(s[i], cmd->buf, cmd->buf_len, 0);
                        if (bytes < 0)
                        {
                            ipcom_printf("sockperf-r: recv failed: %s"IP_LF,
                                         ipcom_strerror(ipcom_errno));
                            return;
                        }

                        if (cmd->testpattern)
                        {
                            if (cmd->echo)
                                ipcom_cmd_sockperf_echo_buf(cmd->buf, bytes, cmd->recv_pattern[i]);
                            for (c = 0; c < (Ip_u32)bytes; c += 8)
                            {
                                if (cmd->buf[c] != '#' && cmd->buf[c] != '>' && cmd->buf[c] != '<')
                                {
                                    ipcom_printf("\nsockperf-r: test pattern error, expected B, D or E found %c(%d) offset %ld"IP_LF,
                                                 cmd->buf[c], (int)cmd->buf[c], c);
                                    ipcom_cmd_sockperf_echo_buf(cmd->buf, bytes, 0);
                                    return;
                                }

                                if (ipcom_atoi(cmd->buf + c + 1) != (int)(cmd->recv_pattern[i]++ % 1000000))
                                {
                                    ipcom_printf("\nsockperf-r: test pattern error, was %d should be %ld offset %ld"IP_LF,
                                                 ipcom_atoi(cmd->buf + c + 1), (cmd->recv_pattern[i] - 1) % 1000000, c);
                                    ipcom_cmd_sockperf_echo_buf(cmd->buf, bytes, 0);
                                    return;
                                }
                            }
                        }

                        if (bytes > 0)
                            total_bytes_read += bytes;
                        else
                        {
                            finished_sockets++;
                            IP_FD_CLR(s[i], &cmd->read_set);
                        }
                    }
                }

                if (cmd->transmit && total_bytes_to_send)
                    ptmo = &tmo;
            }
        }
    }
    ipcom_microtime(&stop);

    if (cmd->transmit)
        ipcom_printf("sockperf-t: %lu bytes sent in %ld ms (%lu kbyte/s)"IP_LF,
                     cmd->num_buf * cmd->buf_len,
                     ipcom_cmd_sockperf_tv_to_msec(&start, &stop),
                     cmd->num_buf * cmd->buf_len / (Ip_u32)ipcom_cmd_sockperf_tv_to_msec(&start, &stop) * 1000 / 1024);
    if (cmd->receive)
        ipcom_printf("sockperf-r: %lu bytes read in %ld ms (%lu kbyte/s)"IP_LF,
                     total_bytes_read,
                     ipcom_cmd_sockperf_tv_to_msec(&start, &stop),
                     total_bytes_read / (Ip_u32)ipcom_cmd_sockperf_tv_to_msec(&start, &stop) * 1000 / 1024);

}