Ejemplo n.º 1
0
int sockets_readh(struct graphhost_t* inst, struct list_t* list,
                  struct list_elem_t* elem) {
    struct socketconn_t* conn = elem->data;
    int error;

    if (conn->readbuflength == 0) {
        conn->readbufoffset = 0;
        conn->readbuflength = 16; /* This should be configurable somewhere */
        conn->readbuf = malloc(conn->readbuflength);
    }

    error = recv(conn->fd, (char*)conn->readbuf,
                 conn->readbuflength - conn->readbufoffset, 0);
    if (error < 1) {
        /* Clean up the socket here */
        sockets_close(list, elem);
        return 0;
    }
    conn->readbufoffset += error;

    if (conn->readbufoffset == conn->readbuflength) {
        sockets_readdoneh(inst, conn->readbuf, conn->readbuflength, list, elem);
        conn->readbufoffset = 0;
        conn->readbuflength = 0;
        free(conn->readbuf);
        conn->readbuf = NULL;
    }

    return 0;
}
Ejemplo n.º 2
0
int main(int argc, char *argv[])
{
	struct sockaddr *address;
	struct sockaddr_in address_in;
	struct sockaddr_in6 address_in6;
	socklen_t addrlen;
	uint8_t *address_start;

	int *socket_ids;
	char *data;
	int index;
	struct timeval time_before;
	struct timeval time_after;

	int rc;

	size = 28;
	verbose = false;
	type = SOCK_DGRAM;
	sockets = 10;
	messages = 10;
	family = PF_INET;
	port = 7;

	/*
	 * Parse the command line arguments.
	 *
	 * Stop before the last argument if it does not start with dash ('-')
	 */
	for (index = 1; (index < argc - 1) || ((index == argc - 1) &&
	    (argv[index][0] == '-')); ++index) {

		/* Options should start with dash ('-') */
		if (argv[index][0] == '-') {
			rc = nettest2_parse_opt(argc, argv, &index);
			if (rc != EOK)
				return rc;
		} else {
			nettest2_print_help();
			return EINVAL;
		}
	}

	/* If not before the last argument containing the address */
	if (index >= argc) {
		printf("Command line error: missing address\n");
		nettest2_print_help();
		return EINVAL;
	}

	/* Prepare the address buffer */

	switch (family) {
	case PF_INET:
		address_in.sin_family = AF_INET;
		address_in.sin_port = htons(port);
		address = (struct sockaddr *) &address_in;
		addrlen = sizeof(address_in);
		address_start = (uint8_t *) &address_in.sin_addr.s_addr;
		break;
	case PF_INET6:
		address_in6.sin6_family = AF_INET6;
		address_in6.sin6_port = htons(port);
		address = (struct sockaddr *) &address_in6;
		addrlen = sizeof(address_in6);
		address_start = (uint8_t *) &address_in6.sin6_addr.s6_addr;
		break;
	default:
		fprintf(stderr, "Address family is not supported\n");
		return EAFNOSUPPORT;
	}

	/* Parse the last argument which should contain the address. */
	rc = inet_pton(family, argv[argc - 1], address_start);
	if (rc != EOK) {
		fprintf(stderr, "Address parse error %d\n", rc);
		return rc;
	}

	/* Check data buffer size. */
	if (size <= 0) {
		fprintf(stderr, "Data buffer size too small (%zu). Using 1024 "
		    "bytes instead.\n", size);
		size = 1024;
	}

	/*
	 * Prepare the buffer. Allocate size bytes plus one for terminating
	 * null character.
	 */
	data = (char *) malloc(size + 1);
	if (!data) {
		fprintf(stderr, "Failed to allocate data buffer.\n");
		return ENOMEM;
	}

	/* Fill buffer with a pattern. */
	nettest2_fill_buffer(data, size);

	/* Check socket count. */
	if (sockets <= 0) {
		fprintf(stderr, "Socket count too small (%d). Using "
		    "2 instead.\n", sockets);
		sockets = 2;
	}

	/*
	 * Prepare the socket buffer.
	 * Allocate count entries plus the terminating null (\0)
	 */
	socket_ids = (int *) malloc(sizeof(int) * (sockets + 1));
	if (!socket_ids) {
		fprintf(stderr, "Failed to allocate receive buffer.\n");
		return ENOMEM;
	}
	socket_ids[sockets] = 0;

	if (verbose)
		printf("Starting tests\n");

	rc = sockets_create(verbose, socket_ids, sockets, family, type);
	if (rc != EOK)
		return rc;

	if (type == SOCK_STREAM) {
		rc = sockets_connect(verbose, socket_ids, sockets,
		    address, addrlen);
		if (rc != EOK)
			return rc;
	}

	if (verbose)
		printf("\n");

	rc = gettimeofday(&time_before, NULL);
	if (rc != EOK) {
		fprintf(stderr, "Get time of day error %d\n", rc);
		return rc;
	}

	rc = sockets_sendto_recvfrom(verbose, socket_ids, sockets, address,
	    &addrlen, data, size, messages);
	if (rc != EOK)
		return rc;

	rc = gettimeofday(&time_after, NULL);
	if (rc != EOK) {
		fprintf(stderr, "Get time of day error %d\n", rc);
		return rc;
	}

	if (verbose)
		printf("\tOK\n");

	printf("sendto + recvfrom tested in %ld microseconds\n",
	    tv_sub(&time_after, &time_before));

	rc = gettimeofday(&time_before, NULL);
	if (rc != EOK) {
		fprintf(stderr, "Get time of day error %d\n", rc);
		return rc;
	}

	rc = sockets_sendto(verbose, socket_ids, sockets, address, addrlen,
	    data, size, messages);
	if (rc != EOK)
		return rc;

	rc = sockets_recvfrom(verbose, socket_ids, sockets, address, &addrlen,
	    data, size, messages);
	if (rc != EOK)
		return rc;

	rc = gettimeofday(&time_after, NULL);
	if (rc != EOK) {
		fprintf(stderr, "Get time of day error %d\n", rc);
		return rc;
	}

	if (verbose)
		printf("\tOK\n");

	printf("sendto, recvfrom tested in %ld microseconds\n",
	    tv_sub(&time_after, &time_before));

	rc = sockets_close(verbose, socket_ids, sockets);
	if (rc != EOK)
		return rc;

	if (verbose)
		printf("\nExiting\n");

	return EOK;
}
Ejemplo n.º 3
0
void* sockets_threadmain(void* arg) {
    int listenfd;
    struct graphhost_t* inst = arg;
    struct socketconn_t* conn;
    struct list_elem_t* elem;
    int maxfd;
    int fd;
    uint8_t ipccmd;

    fd_set readfds;
    fd_set writefds;
    fd_set errorfds;

    pthread_mutex_init(&inst->mutex, NULL);

    /* Create a list to store all the open connections */
    inst->connlist = list_create();
    inst->graphlist = list_create();

    /* Listen on a socket */
    listenfd = sockets_listen_int(inst->port, AF_INET, 0x00000000);
    if (listenfd == -1) {
        pthread_mutex_destroy(&inst->mutex);
        list_destroy(inst->graphlist);
        list_destroy(inst->connlist);
        pthread_exit(NULL);
        return NULL;
    }

    /* Set the running flag after we've finished initializing everything */
    inst->running = 1;

    while (1) {
        /* Clear the fdsets */
        FD_ZERO(&readfds);
        FD_ZERO(&writefds);
        FD_ZERO(&errorfds);

        /* Reset the maxfd */
        maxfd = listenfd;

        /* Add the file descriptors to the list */
        pthread_mutex_lock(&inst->mutex);
        for (elem = inst->connlist->start; elem != NULL; elem = elem->next) {
            conn = elem->data;
            fd = conn->fd;

            if (conn->orphan == 1) continue;

            if (maxfd < fd) maxfd = fd;
            if (conn->selectflags & SOCKET_READ) FD_SET(fd, &readfds);
            if (conn->selectflags & SOCKET_WRITE) FD_SET(fd, &writefds);
            if (conn->selectflags & SOCKET_ERROR) FD_SET(fd, &errorfds);
        }
        pthread_mutex_unlock(&inst->mutex);

        /* Select on the listener fd */
        FD_SET(listenfd, &readfds);

        /* ipcfd will recieve data when the thread needs to exit */
        FD_SET(inst->ipcfd_r, &readfds);

        /* Select on the file descrpitors */
        select(maxfd + 1, &readfds, &writefds, &errorfds, NULL);

        pthread_mutex_lock(&inst->mutex);
        for (elem = inst->connlist->start; elem != NULL; elem = elem->next) {
            conn = elem->data;
            fd = conn->fd;

            if (conn->orphan == 1) continue;

            if (FD_ISSET(fd, &readfds)) {
                /* Handle reading */
                sockets_readh(inst, inst->connlist, elem);
            }
            if (FD_ISSET(fd, &writefds)) {
                /* Handle writing */
                sockets_writeh(inst, inst->connlist, elem);
            }
            if (FD_ISSET(fd, &errorfds)) {
                /* Handle errors */
                sockets_close(inst->connlist, elem);
            }
        }

        /* Close all the file descriptors marked for closing */
        sockets_clear_orphans(inst->connlist);
        pthread_mutex_unlock(&inst->mutex);

        /* Check for listener condition */
        if (FD_ISSET(listenfd, &readfds)) {
            /* Accept connections */
            sockets_accept(inst->connlist, listenfd);
        }

        /* Handle IPC commands */
        if (FD_ISSET(inst->ipcfd_r, &readfds)) {
            read(inst->ipcfd_r, (char*)&ipccmd, 1);
            if (ipccmd == 'x') {
                break;
            }
        }
    }

    /* We're done, clear the running flag and clean up */
    inst->running = 0;
    pthread_mutex_lock(&inst->mutex);

    /* Mark all the open file descriptors for closing */
    for (elem = inst->connlist->start; elem != NULL; elem = elem->next) {
        sockets_close(inst->connlist, elem);
        /* We don't need to delete the element form the
           because we just delete all of them below. */
    }

    /* Actually close all the open file descriptors */
    sockets_clear_orphans(inst->connlist);

    /* Free the list of connections */
    list_destroy(inst->connlist);

    /* Close the listener file descriptor */
    close(listenfd);

    /* Clean up & free the global dataset list */
    for (elem = inst->graphlist->start; elem != NULL; elem = elem->next) {
        free(elem->data);
    }
    list_destroy(inst->graphlist);

    /* Destroy the mutex */
    pthread_mutex_unlock(&inst->mutex);
    pthread_mutex_destroy(&inst->mutex);

    pthread_exit(NULL);
    return NULL;
}
Ejemplo n.º 4
0
static int nettest1_test(int *socket_ids, int nsockets, int nmessages)
{
	int rc;

	if (verbose)
		printf("%d sockets, %d messages\n", nsockets, nmessages);

	rc = sockets_create(verbose, socket_ids, nsockets, family, type);
	if (rc != EOK)
		return rc;

	if (type == SOCK_STREAM) {
		rc = sockets_connect(verbose, socket_ids, nsockets, address,
		    addrlen);
		if (rc != EOK)
			return rc;
	}

	rc = sockets_sendto_recvfrom(verbose, socket_ids, nsockets, address,
	    &addrlen, data, size, nmessages);
	if (rc != EOK)
		return rc;

	rc = sockets_close(verbose, socket_ids, nsockets);
	if (rc != EOK)
		return rc;

	if (verbose)
		printf("\tOK\n");

	/****/

	rc = sockets_create(verbose, socket_ids, nsockets, family, type);
	if (rc != EOK)
		return rc;

	if (type == SOCK_STREAM) {
		rc = sockets_connect(verbose, socket_ids, nsockets, address,
		    addrlen);
		if (rc != EOK)
			return rc;
	}

	rc = sockets_sendto(verbose, socket_ids, nsockets, address, addrlen,
	    data, size, nmessages);
	if (rc != EOK)
		return rc;

	rc = sockets_recvfrom(verbose, socket_ids, nsockets, address, &addrlen,
	    data, size, nmessages);
	if (rc != EOK)
		return rc;

	rc = sockets_close(verbose, socket_ids, nsockets);
	if (rc != EOK)
		return rc;

	if (verbose)
		printf("\tOK\n");

	return EOK;
}