Exemplo n.º 1
0
int testdomain()
{
    int rc;
    int s;
    int op;
    size_t opsz;
    printf("test domain\n");

    s = test_socket (AF_SP, NN_PAIR);

    opsz = sizeof (op);
    rc = nn_getsockopt (s, NN_SOL_SOCKET, NN_DOMAIN, &op, &opsz);
    errno_assert (rc == 0);
    nn_assert (opsz == sizeof (op));
    nn_assert (op == AF_SP);

    opsz = sizeof (op);
    rc = nn_getsockopt (s, NN_SOL_SOCKET, NN_PROTOCOL, &op, &opsz);
    errno_assert (rc == 0);
    nn_assert (opsz == sizeof (op));
    nn_assert (op == NN_PAIR);

    test_close (s);

    return 0;
}
Exemplo n.º 2
0
coroutine void collect(chan workers, int back_router)
{
    //int back_router = nn_socket(AF_SP_RAW, NN_REP);
    //nn_bind(back_router, BACKROUTER);

    int ready;
    size_t ready_sz = sizeof (ready);

    nn_getsockopt(back_router, NN_SOL_SOCKET, NN_RCVFD, &ready, &ready_sz);

    struct nn_msghdr hdr;
    char *body = malloc(sizeof(char)*128);

    while(1){

        char *ctrl = malloc(sizeof(char)*64);
       
        memset(&hdr, 0, sizeof(hdr)); 

        struct nn_iovec iovec;
        iovec.iov_base = body;
        iovec.iov_len = 128;

        hdr.msg_iov = &iovec;
        hdr.msg_iovlen = 1;
        hdr.msg_control = ctrl;
        hdr.msg_controllen = 64;

        fdwait(ready, FDW_IN, -1);
        int rc = nn_recvmsg(back_router, &hdr, NN_DONTWAIT);
        printf("%.*s\n", hdr.msg_iov->iov_len, (char*) hdr.msg_iov->iov_base);
        chs(workers, char*, ctrl); 
    }

}
Exemplo n.º 3
0
Arquivo: enm_drv.c Projeto: basho/enm
int
enm_write_select(EnmData* d, int start)
{
    ErlDrvEvent event;
    int rc;
    size_t optlen = sizeof d->sfd;

    if (start) {
        if (d->b.write_poll)
            return 0;
        if (d->sfd == -1) {
            if (d->protocol == NN_PULL || d->protocol == NN_SUB) {
                errno = EINVAL;
                return -1;
            }
            rc = nn_getsockopt(d->fd, NN_SOL_SOCKET, NN_SNDFD, &d->sfd, &optlen);
            if (rc < 0)
                return -1;
            enm_sockets[d->sfd] = d;
        }
        event = (ErlDrvEvent)(long)d->sfd;
        driver_select(d->port, event, ERL_DRV_WRITE|ERL_DRV_USE, 1);
        d->b.write_poll = 1;
    } else {
        if (!d->b.write_poll)
            return 0;
        assert(d->sfd != -1);
        event = (ErlDrvEvent)(long)d->sfd;
        driver_select(d->port, event, ERL_DRV_WRITE|ERL_DRV_USE, 0);
        d->b.write_poll = 0;
    }
    return 0;
}
Exemplo n.º 4
0
 inline void getsockopt (int level, int option, void *optval,
     size_t *optvallen)
 {
     int rc = nn_getsockopt (s, level, option, optval, optvallen);
     if (nn_slow (rc != 0))
         throw nn::exception ();
 }
Exemplo n.º 5
0
bool pnet_internal_get_socketfd(pnet_socket *socket)
{
    size_t sd_size = sizeof(int);

    if (unlikely(nn_getsockopt(socket->socket_fd, NN_SOL_SOCKET, NN_RCVFD, &socket->recv_fd, &sd_size))) {
        plog_error("pnet_server_start() не удалось получить NN_RCVFD | %s (%d)", nn_strerror(nn_errno()), nn_errno());
        return false;
    }

    if (unlikely(nn_getsockopt(socket->socket_fd, NN_SOL_SOCKET, NN_SNDFD, &socket->send_fd, &sd_size))) {
        plog_error("pnet_server_start() не удалось получить NN_SNDFD | %s (%d)", nn_strerror(nn_errno()), nn_errno());
        return false;
    }

    return true;
}
Exemplo n.º 6
0
int node (const int argc, const char **argv)
{
	int sock    = nn_socket (AF_SP, NN_BUS);
	int sock_fd, efd, nfds;
	struct epoll_event event, events[MAX_EVENTS];
	size_t sz = sizeof(sock_fd);
	nn_getsockopt(sock, NN_SOL_SOCKET, NN_RCVFD, &sock_fd, &sz);
	assert(sock >= 0);
	assert(nn_bind (sock, argv[2]) >= 0);
	sleep (1); // wait for connections
	if (argc >= 3) {
		int x;
		for(x = 3; x < argc; x++)
			assert(nn_connect(sock, argv[x]) >= 0);
	}
	efd = epoll_create(MAX_EVENTS);
	assert(efd != -1);

	event.data.fd = sock_fd;
	event.events  = EPOLLIN;
	assert(epoll_ctl(efd, EPOLL_CTL_ADD, sock_fd, &event) != -1);

	// wait for connections
	sleep(1);
	int to = 100;
	assert(nn_setsockopt (sock, NN_SOL_SOCKET, NN_RCVTIMEO, &to, sizeof(to)) >= 0);

	// SEND
	int sz_n = strlen(argv[1]) + 1; // '\0' too
	printf ("%s: SENDING '%s' ONTO BUS\n", argv[1], argv[1]);
	int send = nn_send (sock, argv[1], sz_n, 0);
	assert (send == sz_n);

	for(;;) {
		nfds = epoll_wait(efd, events, MAX_EVENTS, -1);
		assert(nfds != -1);

		int n, recv;
		for (n = 0; n < nfds; ++n) {
			if (events[n].data.fd == sock_fd) {
				char *buf = NULL;
				recv = nn_recv(sock, &buf, NN_MSG, 0);
				if (recv >= 0) {
					printf ("%s: RECEIVED '%s' FROM BUS\n", argv[1], buf);
					nn_freemsg (buf);
				}
			}
		}
	}
	return nn_shutdown (sock, 0);
}
Exemplo n.º 7
0
int nn_device_loopback (struct nn_device_recipe *device,int s)
{
    int rc;
    int op;
    size_t opsz;

    /*  Check whether the socket is a "raw" socket. */
    opsz = sizeof (op);
    rc = nn_getsockopt (s, NN_SOL_SOCKET, NN_DOMAIN, &op, &opsz);
    errno_assert (rc == 0);
    nn_assert (opsz == sizeof (op));
    if (op != AF_SP_RAW) {
        errno = EINVAL;
        return -1;
    }

    while (1) {
        rc = nn_device_mvmsg (device,s, s, 0);
        if (nn_slow (rc < 0))
            return -1;
    }
}
Exemplo n.º 8
0
Arquivo: enm_drv.c Projeto: basho/enm
static ErlDrvSSizeT
enm_create_socket(EnmData* d, EnmArgs* args)
{
    ErlDrvSSizeT res;
    int rc, domain, err, opt;
    size_t optlen = sizeof d->sfd;

    d->fd = d->sfd = d->rfd = -1;
    d->b.active = ENM_TRUE;
    while (args->index < args->len) {
        opt = *args->buf++;
        args->index++;
        switch (opt) {
        case ENM_ACTIVE:
        case ENM_RAW:
        case ENM_BINARY:
        case ENM_DEADLINE:
        case ENM_SUBSCRIBE:
        case ENM_RESEND_IVL:
        case ENM_SNDBUF:
        case ENM_RCVBUF:
        case ENM_NODELAY:
        case ENM_IPV4ONLY:
            if ((res = enm_setopts_priv(d, opt, args)) != 0)
                return res;
            break;
        default:
            return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
        }
    }
    domain = d->b.raw ? AF_SP_RAW : AF_SP;
    d->fd = nn_socket(domain, d->protocol);
    if (d->fd < 0)
        return enm_errno_tuple(*args->rbuf, errno);
    if (args->deadline != 0) {
        rc = nn_setsockopt(d->fd, NN_SURVEYOR, NN_SURVEYOR_DEADLINE,
                           &args->deadline, sizeof args->deadline);
        if (rc < 0) {
            err = errno;
            nn_close(d->fd);
            d->fd = -1;
            return enm_errno_tuple(*args->rbuf, err);
        }
    }
    if (args->resend_ivl != 0) {
        rc = nn_setsockopt(d->fd, NN_REQ, NN_REQ_RESEND_IVL,
                           &args->resend_ivl, sizeof args->resend_ivl);
        if (rc < 0) {
            err = errno;
            nn_close(d->fd);
            d->fd = -1;
            return enm_errno_tuple(*args->rbuf, err);
        }
    }
    if (args->b.topic_seen) {
        rc = nn_setsockopt(d->fd, NN_SUB, NN_SUB_SUBSCRIBE,
                           args->topic, strlen(args->topic));
        if (rc < 0) {
            err = errno;
            nn_close(d->fd);
            d->fd = -1;
            return enm_errno_tuple(*args->rbuf, err);
        }
    }
    if (d->protocol != NN_PULL && d->protocol != NN_SUB) {
        rc = nn_getsockopt(d->fd, NN_SOL_SOCKET, NN_SNDFD, &d->sfd, &optlen);
        if (rc < 0) {
            err = errno;
            nn_close(d->fd);
            d->fd = -1;
            return enm_errno_tuple(*args->rbuf, err);
        }
        enm_sockets[d->sfd] = d;
        d->b.writable = 1;
        if (args->sndbuf != 0) {
            rc = nn_setsockopt(d->fd, NN_SOL_SOCKET, NN_SNDBUF,
                               &args->sndbuf, sizeof args->sndbuf);
            if (rc < 0) {
                err = errno;
                nn_close(d->fd);
                d->fd = -1;
                d->sfd = -1;
                return enm_errno_tuple(*args->rbuf, err);
            }
        } else {
            optlen = sizeof args->sndbuf;
            rc = nn_getsockopt(d->fd, NN_SOL_SOCKET, NN_SNDBUF,
                               &args->sndbuf, &optlen);
            if (rc < 0) {
                err = errno;
                nn_close(d->fd);
                d->fd = -1;
                d->sfd = -1;
                return enm_errno_tuple(*args->rbuf, err);
            }
        }
        if (args->sndbuf != 0) {
            ErlDrvSizeT low = args->sndbuf >> 1, high = args->sndbuf;
            erl_drv_busy_msgq_limits(d->port, &low, &high);
        }
Exemplo n.º 9
0
Arquivo: client.c Projeto: tnako/DP
void* run_test(void  *threadid)
{
    long tid = (long)threadid;

    for (int cycle = 0; cycle < CYCLES; ++cycle) {

        GHashTable* sockets = g_hash_table_new(g_direct_hash, g_direct_equal);

        int epfd = epoll_create(MAX_CONNECTIONS);
        if (epfd < 1) {
            printf("can't create epoll\n");
            if (sockets) {
                g_hash_table_destroy(sockets);
                sockets = NULL;
            }
            return NULL;
        }

        struct epoll_event ev, ev_read, events[MAX_CONNECTIONS];
        memset(&ev, 0x0, sizeof(struct epoll_event));
        memset(&ev_read, 0x0, sizeof(struct epoll_event));
        memset(events, 0x0, sizeof(struct epoll_event) * MAX_CONNECTIONS);

        ev.events = EPOLLONESHOT | EPOLLOUT | EPOLLRDHUP;
        ev_read.events = EPOLLIN | EPOLLRDHUP;

        //unsigned int sends = 0;

        int sdIN[MAX_CONNECTIONS] = { 0 };
        int sdOUT[MAX_CONNECTIONS] = { 0 };
        int requester[MAX_CONNECTIONS] = { 0 };

        for (int i = 0; i < MAX_CONNECTIONS; i++) {
            requester[i] = nn_socket(AF_SP, NN_REQ);
            if(requester[i] < 0) {
                flockfile(stdout);
                printf("nn_socket() %s (%d)\n", nn_strerror(nn_errno()), nn_errno());
                funlockfile(stdout);
                exit(1);
            }
            int val = 1;
            nn_setsockopt(requester[i], NN_TCP, NN_TCP_NODELAY, &val, sizeof(val));
            int ret = nn_connect(requester[i], "tcp://10.2.142.102:12345");
            //int ret = nn_connect(requester[i], "tcp://127.0.0.1:12345");
            if (ret < 0) {
                flockfile(stdout);
                printf("nn_connect() %s (%d)\n", nn_strerror(nn_errno()), nn_errno());
                funlockfile(stdout);
            }
            size_t sd_size = sizeof(int);
            nn_getsockopt(requester[i], NN_SOL_SOCKET, NN_SNDFD, &sdOUT[i], &sd_size);
            nn_getsockopt(requester[i], NN_SOL_SOCKET, NN_RCVFD, &sdIN[i], &sd_size);
            //printf("fd = %d | %d\n", sdOUT[i], sdIN[i]);

            if (requester[i] >= 0) {
                g_hash_table_insert(sockets, GINT_TO_POINTER(i), GINT_TO_POINTER(0));
                ev.data.fd = sdOUT[i];
                if (epoll_ctl(epfd, EPOLL_CTL_ADD, sdOUT[i], &ev)) {
                    printf("can't epoll_ctl\n");
                    if (sockets) {
                        g_hash_table_destroy(sockets);
                        sockets = NULL;
                    }
                    nn_close(requester[i]);
                    return NULL;
                }
                ev_read.data.fd = sdIN[i];
                if (epoll_ctl(epfd, EPOLL_CTL_ADD, sdIN[i], &ev_read)) {
                    printf("can't epoll_ctl\n");
                    if (sockets) {
                        g_hash_table_destroy(sockets);
                        sockets = NULL;
                    }
                    nn_close(requester[i]);
                    return NULL;
                }
            }
        }

        while (1) {
            int rv = epoll_wait(epfd, events, MAX_CONNECTIONS, 5000);

            if (rv == 0) {
                break;
            } else if (rv < 0) {
                flockfile(stdout);
                printf("#%ld | can't epoll_wait: %s (%d)\n", tid, strerror(errno), errno);
                funlockfile(stdout);
                break;
            }

            int rv_ch = 0;
            for (int epoll_event = 0; epoll_event < MAX_CONNECTIONS ; epoll_event++) {
                if (rv_ch++ == rv) {
                    break;
                }
                if (events[epoll_event].events & EPOLLIN) {
                    int num = -1;
                    for (int i = 0; i < MAX_CONNECTIONS; i++) {
                        if (events[epoll_event].data.fd == sdIN[i]) {
                            num = i;
                            break;
                        }
                    }
                    if (num == -1) {
                        //nn_term();
                        flockfile(stdout);
                        printf("IN | Can`t find socket\n");
                        funlockfile(stdout);
                        exit(1);
                    }

                    char buffer[BUFFER_READ];
                    if (nn_recv(requester[num], buffer, BUFFER_READ, NN_DONTWAIT) < 0) {
                        if (nn_errno() == EAGAIN || nn_errno() == EFSM) {
                            continue;
                        }
                        flockfile(stdout);
                        printf("#%ld | can't recv on socket #%d %s (%d)\n", tid, requester[num], nn_strerror(nn_errno()), nn_errno());
                        funlockfile(stdout);
                        exit(1);
                    } else {
                        int a = GPOINTER_TO_INT(g_hash_table_lookup(sockets, GINT_TO_POINTER(num)));
                        if (a < MESSAGES) {
                            ev.data.fd = sdOUT[num];
                            if (epoll_ctl(epfd, EPOLL_CTL_MOD, sdOUT[num], &ev)) {
                                printf("can't epoll_ctl\n");
                                if (sockets) {
                                    g_hash_table_destroy(sockets);
                                    sockets = NULL;
                                }
                                nn_close(requester[num]);
                                return NULL;
                            }
                        }
                        ++reads_counter;
                        //printf("recv %d\n", events[epoll_event].data.fd);
                    }
                }
                if (events[epoll_event].events & (EPOLLERR | EPOLLHUP | EPOLLRDHUP)) {
                    ++discon_counter;
                    flockfile(stdout);
                    printf("#%ld | Debug: Close conn: %d - 0x%04x\n", tid, events[epoll_event].data.fd, events[epoll_event].events);
                    funlockfile(stdout);

                    if (epoll_ctl(epfd, EPOLL_CTL_DEL, events[epoll_event].data.fd, NULL)) {
                        flockfile(stdout);
                        printf("#%ld | Couldn't epoll_ctl2, fd=%d, error: %s (%d)\n", tid, events[epoll_event].data.fd, strerror(errno), errno);
                        funlockfile(stdout);
                    }
                    //shutdown(events[epoll_event].data.fd, SHUT_RDWR);
                    continue;
                }
                if (events[epoll_event].events & EPOLLOUT) {

                    int num = -1;
                    for (int i = 0; i < MAX_CONNECTIONS; i++) {
                        if (events[epoll_event].data.fd == sdOUT[i]) {
                            num = i;
                            break;
                        }
                    }
                    if (num == -1) {
                        //nn_term();
                        flockfile(stdout);
                        printf("OUT | Can`t find socket\n");
                        funlockfile(stdout);
                        exit(1);
                    }
                    
		    msgpack_sbuffer sbuf;
		    msgpack_sbuffer_init(&sbuf);
		    msgpack_packer pck;
		    msgpack_packer_init(&pck, &sbuf, msgpack_sbuffer_write);

		    msgpack_pack_raw(&pck, 5);
		    msgpack_pack_raw_body(&pck, "Hello", 10);

		    int size = sbuf.size;
		    char *buf = malloc(sbuf.size);
		    memcpy(buf, sbuf.data, sbuf.size);
		    msgpack_sbuffer_destroy(&sbuf);
                    
                    if (nn_send(requester[num], buf, size, NN_DONTWAIT) < 0) {
                        if (nn_errno() == EAGAIN) {
                            continue;
                        }
                        ++discon_counter;
                        flockfile(stdout);
                        printf("#%ld | can't send on socket #%d %s (%d)\n", tid, num, nn_strerror(nn_errno()), nn_errno());
                        funlockfile(stdout);

                        if (epoll_ctl(epfd, EPOLL_CTL_DEL, events[epoll_event].data.fd, NULL)) {
                            flockfile(stdout);
                            printf("#%ld | Couldn't epoll_ctl4, fd=%d, error: %s (%d)\n", tid, events[epoll_event].data.fd, strerror(errno), errno);
                            funlockfile(stdout);
                            exit(1);
                        }

                        nn_close(requester[num]);
			free(buf);

                        break;
                    } else {
                        //printf("send %d\n", events[epoll_event].data.fd);
                        int a = GPOINTER_TO_INT(g_hash_table_lookup(sockets, GINT_TO_POINTER(num)));
                        g_hash_table_insert(sockets, GINT_TO_POINTER(num), GINT_TO_POINTER(++a));

                        update(1);
                        ++sends_counter;
			free(buf);
                    }
                }
            }
            fflush(stdout);
        }

        for (int i = 0; i < MAX_CONNECTIONS; i++) {
            if (GPOINTER_TO_INT(g_hash_table_lookup(sockets, GINT_TO_POINTER(i))) == 0) {
                ++sockets_wo_send_counter;
            }
            nn_close(requester[i]);
        }

        if (sockets) {
            g_hash_table_foreach(sockets, find_min_max, NULL);
            g_hash_table_destroy(sockets);
        }
    }
    return NULL;
}
Exemplo n.º 10
0
int nn_poll (struct nn_pollfd *fds, int nfds, int timeout)
{
    int rc;
    int i;
    fd_set fdset;
    SOCKET fd;
    int res;
    size_t sz;
    struct timeval tv;

    /*  Fill in the fdset, as appropriate. */
    FD_ZERO (&fdset);
    for (i = 0; i != nfds; ++i) {
        if (fds [i].events & NN_POLLIN) {
            sz = sizeof (fd);
            rc = nn_getsockopt (fds [i].fd, NN_SOL_SOCKET, NN_RCVFD, &fd, &sz);
            if (nn_slow (rc < 0)) {
                errno = -rc;
                return -1;
            }
            nn_assert (sz == sizeof (fd));
            FD_SET (fd, &fdset);
        }
        if (fds [i].events & NN_POLLOUT) {
            sz = sizeof (fd);
            rc = nn_getsockopt (fds [i].fd, NN_SOL_SOCKET, NN_SNDFD, &fd, &sz);
            if (nn_slow (rc < 0)) {
                errno = -rc;
                return -1;
            }
            nn_assert (sz == sizeof (fd));
            FD_SET (fd, &fdset);
        }
    }

    /*  Do the polling itself. */
    tv.tv_sec = timeout / 1000;
    tv.tv_usec = timeout % 1000 * 1000;
    rc = select (-1, &fdset, NULL, NULL, &tv);
    if (nn_slow (rc == 0))
        return 0;
    if (nn_slow (rc == SOCKET_ERROR)) {
        errno = nn_err_wsa_to_posix (WSAGetLastError ());
        return -1;
    }

    /*  Move the results from fdset to the nanomsg pollset. */
    res = 0;
    for (i = 0; i != nfds; ++i) {
        fds [i].revents = 0;
        if (fds [i].events & NN_POLLIN) {
            sz = sizeof (fd);
            rc = nn_getsockopt (fds [i].fd, NN_SOL_SOCKET, NN_RCVFD, &fd, &sz);
            if (nn_slow (rc < 0)) {
                errno = -rc;
                return -1;
            }
            nn_assert (sz == sizeof (fd));
            if (FD_ISSET (fd, &fdset))
                fds [i].revents |= NN_POLLIN;
        }
        if (fds [i].events & NN_POLLOUT) {
            sz = sizeof (fd);
            rc = nn_getsockopt (fds [i].fd, NN_SOL_SOCKET, NN_SNDFD, &fd, &sz);
            if (nn_slow (rc < 0)) {
                errno = -rc;
                return -1;
            }
            nn_assert (sz == sizeof (fd));
            if (FD_ISSET (fd, &fdset))
                fds [i].revents |= NN_POLLOUT;
        }
        if (fds [i].revents)
            ++res;
    }

    return res;
}
Exemplo n.º 11
0
int nn_poll (struct nn_pollfd *fds, int nfds, int timeout)
{
    int rc;
    int i;
    int pos;
    int fd;
    int res;
    size_t sz;
    struct pollfd *pfd;

    /*  Construct a pollset to be used with OS-level 'poll' function. */
    pfd = nn_alloc (sizeof (struct pollfd) * nfds * 2, "pollset");
    alloc_assert (pfd);
    pos = 0;
    for (i = 0; i != nfds; ++i) {
        if (fds [i].events & NN_POLLIN) {
            sz = sizeof (fd);
            rc = nn_getsockopt (fds [i].fd, NN_SOL_SOCKET, NN_RCVFD, &fd, &sz);
            if (nn_slow (rc < 0)) {
                nn_free (pfd);
                errno = -rc;
                return -1;
            }
            nn_assert (sz == sizeof (fd));
            pfd [pos].fd = fd;
            pfd [pos].events = POLLIN;
            ++pos;
        }
        if (fds [i].events & NN_POLLOUT) {
            sz = sizeof (fd);
            rc = nn_getsockopt (fds [i].fd, NN_SOL_SOCKET, NN_SNDFD, &fd, &sz);
            if (nn_slow (rc < 0)) {
                nn_free (pfd);
                errno = -rc;
                return -1;
            }
            nn_assert (sz == sizeof (fd));
            pfd [pos].fd = fd;
            pfd [pos].events = POLLIN;
            ++pos;
        }
    }    

    /*  Do the polling itself. */
    rc = poll (pfd, pos, timeout);
    if (nn_slow (rc <= 0)) {
        res = errno;
        nn_free (pfd);
        errno = res;
        return rc;
    }

    /*  Move the results from OS-level poll to nn_poll's pollset. */
    res = 0;
    pos = 0;
    for (i = 0; i != nfds; ++i) {
        fds [i].revents = 0;
        if (fds [i].events & NN_POLLIN) {
            if (pfd [pos].revents & POLLIN)
                fds [i].revents |= NN_POLLIN;
            ++pos;
        }
        if (fds [i].events & NN_POLLOUT) {
            if (pfd [pos].revents & POLLIN)
                fds [i].revents |= NN_POLLOUT;
            ++pos;
        }
        if (fds [i].revents)
            ++res;
    }

    nn_free (pfd);
    return res;
}
Exemplo n.º 12
0
int nn_device_entry(struct nn_device_recipe *device,int s1, int s2,
    int flags) 
{
    int rc;
    int op1;
    int op2;
    nn_fd s1rcv;
    nn_fd s1snd;
    nn_fd s2rcv;
    nn_fd s2snd;
    size_t opsz;

    /*  At least one socket must be specified. */
    if (device->required_checks & NN_CHECK_AT_LEAST_ONE_SOCKET) {
        if (s1 < 0 && s2 < 0) {
            errno = EBADF;
            return -1;
        }
    }

    /*  Handle the case when there's only one socket in the device. */
    if (device->required_checks & NN_CHECK_ALLOW_LOOPBACK) {
        if (s2 < 0)
            return nn_device_loopback (device,s1);
        if (s1 < 0)
            return nn_device_loopback (device,s2);
    }

    /*  Check whether both sockets are "raw" sockets. */
    if (device->required_checks & NN_CHECK_REQUIRE_RAW_SOCKETS) {
        opsz = sizeof (op1);
        rc = nn_getsockopt (s1, NN_SOL_SOCKET, NN_DOMAIN, &op1, &opsz);
        errno_assert (rc == 0);
        nn_assert (opsz == sizeof (op1));
        opsz = sizeof (op2);
        rc = nn_getsockopt (s2, NN_SOL_SOCKET, NN_DOMAIN, &op2, &opsz);
        errno_assert (rc == 0);
        nn_assert (opsz == sizeof (op2));
        if (op1 != AF_SP_RAW || op2 != AF_SP_RAW) {
            errno = EINVAL;
            return -1;
        }
    }

    /*  Check whether both sockets are from the same protocol. */
    if (device->required_checks & NN_CHECK_SAME_PROTOCOL_FAMILY) {
        opsz = sizeof (op1);
        rc = nn_getsockopt (s1, NN_SOL_SOCKET, NN_PROTOCOL, &op1, &opsz);
        errno_assert (rc == 0);
        nn_assert (opsz == sizeof (op1));
        opsz = sizeof (op2);
        rc = nn_getsockopt (s2, NN_SOL_SOCKET, NN_PROTOCOL, &op2, &opsz);
        errno_assert (rc == 0);
        nn_assert (opsz == sizeof (op2));
        if (op1 / 16 != op2 / 16) {
            errno = EINVAL;
            return -1;
        }
    }

    /*  Get the file descriptors for polling. */
    opsz = sizeof (s1rcv);
    rc = nn_getsockopt (s1, NN_SOL_SOCKET, NN_RCVFD, &s1rcv, &opsz);
    if (rc < 0 && nn_errno () == ENOPROTOOPT)
        s1rcv = -1;
    else {
        nn_assert (rc == 0);
        nn_assert (opsz == sizeof (s1rcv));
        nn_assert (s1rcv >= 0);
    }
    opsz = sizeof (s1snd);
    rc = nn_getsockopt (s1, NN_SOL_SOCKET, NN_SNDFD, &s1snd, &opsz);
    if (rc < 0 && nn_errno () == ENOPROTOOPT)
        s1snd = -1;
    else {
        nn_assert (rc == 0);
        nn_assert (opsz == sizeof (s1snd));
        nn_assert (s1snd >= 0);
    }
    opsz = sizeof (s2rcv);
    rc = nn_getsockopt (s2, NN_SOL_SOCKET, NN_RCVFD, &s2rcv, &opsz);
    if (rc < 0 && nn_errno () == ENOPROTOOPT)
        s2rcv = -1;
    else {
        nn_assert (rc == 0);
        nn_assert (opsz == sizeof (s2rcv));
        nn_assert (s2rcv >= 0);
    }
    opsz = sizeof (s2snd);
    rc = nn_getsockopt (s2, NN_SOL_SOCKET, NN_SNDFD, &s2snd, &opsz);
    if (rc < 0 && nn_errno () == ENOPROTOOPT)
        s2snd = -1;
    else {
        nn_assert (rc == 0);
        nn_assert (opsz == sizeof (s2snd));
        nn_assert (s2snd >= 0);
    }
    if (device->required_checks & NN_CHECK_SOCKET_DIRECTIONALITY) {
        /*  Check the directionality of the sockets. */
        if (s1rcv != -1 && s2snd == -1) {
            errno = EINVAL;
            return -1;
        }
        if (s1snd != -1 && s2rcv == -1) {
            errno = EINVAL;
            return -1;
        }
        if (s2rcv != -1 && s1snd == -1) {
            errno = EINVAL;
            return -1;
        }
        if (s2snd != -1 && s1rcv == -1) {
            errno = EINVAL;
            return -1;
        }
    }

    /*  Two-directional device. */
    if (device->required_checks & NN_CHECK_ALLOW_BIDIRECTIONAL) {
        if (s1rcv != -1 && s1snd != -1 && s2rcv != -1 && s2snd != -1)
            return nn_device_twoway (device, s1, s1rcv, s1snd,
                s2, s2rcv, s2snd);
    }

    if (device->required_checks & NN_CHECK_ALLOW_UNIDIRECTIONAL) {
        /*  Single-directional device passing messages from s1 to s2. */
        if (s1rcv != -1 && s1snd == -1 && s2rcv == -1 && s2snd != -1)
            return nn_device_oneway (device,s1, s1rcv, s2, s2snd);

        /*  Single-directional device passing messages from s2 to s1. */
        if (s1rcv == -1 && s1snd != -1 && s2rcv != -1 && s2snd == -1)
            return nn_device_oneway (device,s2, s2rcv, s1, s1snd);
    }

    /*  This should never happen. */
    nn_assert (0);
}
Exemplo n.º 13
0
int main (int argc, const char *argv[])
{
    int rc;
    int sb;
    int sc;
    int sb2;
    int opt;
    size_t sz;
    int i;
    char any_address[128];

    test_addr_from (socket_address, "ws", "127.0.0.1",
            get_test_port (argc, argv));

    test_addr_from (any_address, "ws", "*",
            get_test_port (argc, argv));

    /*  Try closing bound but unconnected socket. */
    sb = test_socket (AF_SP, NN_PAIR);
    test_bind (sb, any_address);
    test_close (sb);

    /*  Try closing a TCP socket while it not connected. At the same time
        test specifying the local address for the connection. */
    sc = test_socket (AF_SP, NN_PAIR);
    test_connect (sc, socket_address);
    test_close (sc);

    /*  Open the socket anew. */
    sc = test_socket (AF_SP, NN_PAIR);

    /*  Check socket options. */
    sz = sizeof (opt);
    rc = nn_getsockopt (sc, NN_WS, NN_WS_MSG_TYPE, &opt, &sz);
    errno_assert (rc == 0);
    nn_assert (sz == sizeof (opt));
    nn_assert (opt == NN_WS_MSG_TYPE_BINARY);

    /*  Default port 80 should be assumed if not explicitly declared. */
    rc = nn_connect (sc, "ws://127.0.0.1");
    errno_assert (rc >= 0);

    /*  Try using invalid address strings. */
    rc = nn_connect (sc, "ws://*:");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_connect (sc, "ws://*:1000000");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_connect (sc, "ws://*:some_port");
    nn_assert (rc < 0);
    rc = nn_connect (sc, "ws://eth10000;127.0.0.1:5555");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == ENODEV);

    rc = nn_bind (sc, "ws://127.0.0.1:");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_bind (sc, "ws://127.0.0.1:1000000");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_bind (sc, "ws://eth10000:5555");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == ENODEV);

    rc = nn_connect (sc, "ws://:5555");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_connect (sc, "ws://-hostname:5555");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_connect (sc, "ws://abc.123.---.#:5555");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_connect (sc, "ws://[::1]:5555");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_connect (sc, "ws://abc.123.:5555");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_connect (sc, "ws://abc...123:5555");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_connect (sc, "ws://.123:5555");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);

    test_close (sc);

    sb = test_socket (AF_SP, NN_PAIR);
    test_bind (sb, socket_address);
    sc = test_socket (AF_SP, NN_PAIR);
    test_connect (sc, socket_address);

    /*  Ping-pong test. */
    for (i = 0; i != 100; ++i) {

        test_send (sc, "ABC");
        test_recv (sb, "ABC");

        test_send (sb, "DEF");
        test_recv (sc, "DEF");
    }

    /*  Batch transfer test. */
    for (i = 0; i != 100; ++i) {
        test_send (sc, "0123456789012345678901234567890123456789");
    }
    for (i = 0; i != 100; ++i) {
        test_recv (sb, "0123456789012345678901234567890123456789");
    }

    test_close (sc);
    test_close (sb);

    /*  Test two sockets binding to the same address. */
    sb = test_socket (AF_SP, NN_PAIR);
    test_bind (sb, socket_address);
    sb2 = test_socket (AF_SP, NN_PAIR);

    rc = nn_bind (sb2, socket_address);
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EADDRINUSE);
    test_close(sb);
    test_close(sb2);

    /*  Test that NN_RCVMAXSIZE can be -1, but not lower */
    sb = test_socket (AF_SP, NN_PAIR);
    opt = -1;
    rc = nn_setsockopt (sb, NN_SOL_SOCKET, NN_RCVMAXSIZE, &opt, sizeof (opt));
    nn_assert (rc >= 0);
    opt = -2;
    rc = nn_setsockopt (sb, NN_SOL_SOCKET, NN_RCVMAXSIZE, &opt, sizeof (opt));
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    test_close (sb);

    /*  Test NN_RCVMAXSIZE limit */
    sb = test_socket (AF_SP, NN_PAIR);
    test_bind (sb, socket_address);
    sc = test_socket (AF_SP, NN_PAIR);
    test_connect (sc, socket_address);
    opt = 1000;
    test_setsockopt (sc, NN_SOL_SOCKET, NN_SNDTIMEO, &opt, sizeof (opt));
    nn_assert (opt == 1000);
    opt = 1000;
    test_setsockopt (sb, NN_SOL_SOCKET, NN_RCVTIMEO, &opt, sizeof (opt));
    nn_assert (opt == 1000);
    opt = 4;
    test_setsockopt (sb, NN_SOL_SOCKET, NN_RCVMAXSIZE, &opt, sizeof (opt));
    test_send (sc, "ABC");
    test_recv (sb, "ABC");
    test_send (sc, "ABCD");
    test_recv (sb, "ABCD");
    test_send (sc, "ABCDE");
    test_drop (sb, ETIMEDOUT);

    /*  Increase the size limit, reconnect, then try sending again. The reason a
        reconnect is necessary is because after a protocol violation, the
        connecting socket will not continue automatic reconnection attempts. */
    opt = 5;
    test_setsockopt (sb, NN_SOL_SOCKET, NN_RCVMAXSIZE, &opt, sizeof (opt));
    test_connect (sc, socket_address);
    test_send (sc, "ABCDE");
    test_recv (sb, "ABCDE");
    test_close (sb);
    test_close (sc);

    test_text ();

    /*  Test closing a socket that is waiting to connect. */
    sc = test_socket (AF_SP, NN_PAIR);
    test_connect (sc, socket_address);
    nn_sleep (100);
    test_close (sc);

    return 0;
}
Exemplo n.º 14
0
int getevents (int s, int events, int timeout)
{
    int rc;
    fd_set pollset;
#if defined NN_HAVE_WINDOWS
    SOCKET rcvfd;
    SOCKET sndfd;
#else
    int rcvfd;
    int sndfd;
    int maxfd;
#endif
    size_t fdsz;
    struct timeval tv;
    int revents;

#if !defined NN_HAVE_WINDOWS
    maxfd = 0;
#endif
    FD_ZERO (&pollset);

    if (events & NN_IN) {
        fdsz = sizeof (rcvfd);
        rc = nn_getsockopt (s, NN_SOL_SOCKET, NN_RCVFD, (char*) &rcvfd, &fdsz);
        errno_assert (rc == 0);
        nn_assert (fdsz == sizeof (rcvfd));
        FD_SET (rcvfd, &pollset);
#if !defined NN_HAVE_WINDOWS
        if (rcvfd + 1 > maxfd)
            maxfd = rcvfd + 1;
#endif
    }

    if (events & NN_OUT) {
        fdsz = sizeof (sndfd);
        rc = nn_getsockopt (s, NN_SOL_SOCKET, NN_SNDFD, (char*) &sndfd, &fdsz);
        errno_assert (rc == 0);
        nn_assert (fdsz == sizeof (sndfd));
        FD_SET (sndfd, &pollset);
#if !defined NN_HAVE_WINDOWS
        if (sndfd + 1 > maxfd)
            maxfd = sndfd + 1;
#endif
    }

    if (timeout >= 0) {
        tv.tv_sec = timeout / 1000;
        tv.tv_usec = (timeout % 1000) * 1000;
    }
#if defined NN_HAVE_WINDOWS
    rc = select (0, &pollset, NULL, NULL, timeout < 0 ? NULL : &tv);
    wsa_assert (rc != SOCKET_ERROR);
#else
    rc = select (maxfd, &pollset, NULL, NULL, timeout < 0 ? NULL : &tv);
    errno_assert (rc >= 0);
#endif
    revents = 0;
    if ((events & NN_IN) && FD_ISSET (rcvfd, &pollset))
        revents |= NN_IN;
    if ((events & NN_OUT) && FD_ISSET (sndfd, &pollset))
        revents |= NN_OUT;
    return revents;
}
Exemplo n.º 15
0
int get_rec_sockfd(int sock) {
  int rcvfd;
  size_t rcvfd_sz = sizeof(rcvfd);
  nn_getsockopt(sock, NN_SOL_SOCKET, NN_RCVFD, &rcvfd, &rcvfd_sz);
  return rcvfd;
}
Exemplo n.º 16
0
static gboolean gst_nanomsgsrc_init_sockets(GstNanomsgSrc *nanomsgsrc)
{
	/* This function must be called with a mutex lock */

	int rc;
	size_t watch_fd_size = sizeof(nanomsgsrc->watch_fd);
	gchar const *actual_uri;

	/* No URI -> cannot initialize anything */
	if (nanomsgsrc->uri == NULL)
	{
		GST_ELEMENT_ERROR(nanomsgsrc, RESOURCE, NOT_FOUND, ("No URI specified"), (NULL));
		return FALSE;
	}

	/* Check for the URI scheme prefix */
	if (!g_str_has_prefix(nanomsgsrc->uri, PROTOCOL_PREFIX))
	{
		GST_ELEMENT_ERROR(nanomsgsrc, RESOURCE, NOT_FOUND, ("URI starts with the wrong prefix"), ("URI: %s , expected prefix: \"" PROTOCOL_PREFIX "\"", nanomsgsrc->uri));
		return FALSE;
	}
	
	/* Get the actual nanomsg URI, without the prefix */
	actual_uri = PROTOCOLSTR_REMOVE_PREFIX(nanomsgsrc->uri);
	GST_DEBUG_OBJECT(nanomsgsrc, "URI without the prefix: %s", actual_uri);

	/* Cleanup any existing sockets before initializing new ones */
	gst_nanomsgsrc_shutdown_sockets(nanomsgsrc);


	/* Set up the control pipe file descriptors */
	if (G_UNLIKELY(pipe(nanomsgsrc->ctrl_fds) < 0))
	{
		GST_ERROR_OBJECT(nanomsgsrc, "could not create control pipe: %s", strerror(errno));
		goto failure;
	}


	/* The actual SP socket setup */

	/* Create a SP socket, using the currently configured protocol */
	if (G_UNLIKELY((nanomsgsrc->main_fd = nn_socket(AF_SP, nanomsgsrc->protocol)) < 0))
	{
		GST_ERROR_OBJECT(nanomsgsrc, "could not create SP socket: %s", strerror(errno));
		goto failure;
	}

	/* Configure the socket with the given URI */
	rc = 0;
	switch (nanomsgsrc->protocol)
	{
		case NN_PULL:
			rc = nn_bind(nanomsgsrc->main_fd, actual_uri);
			break;

		case NN_SUB:
			rc = (rc < 0) ? rc : nn_setsockopt(nanomsgsrc->main_fd, NN_SUB, NN_SUB_SUBSCRIBE, (nanomsgsrc->subscription_topic != NULL ? nanomsgsrc->subscription_topic : ""), 0);
			rc = (rc < 0) ? rc : nn_connect(nanomsgsrc->main_fd, actual_uri);
			break;

		default:
			GST_ERROR_OBJECT(nanomsgsrc, "invalid protocol value %d", nanomsgsrc->protocol);
			g_assert_not_reached();
	}

	if (G_UNLIKELY(rc < 0))
	{
		GST_ERROR_OBJECT(nanomsgsrc, "could not configure the SP socket: %s", strerror(errno));
		goto failure;
	}

	/* Retrieve the watch FD for use with poll() */
	if (G_UNLIKELY(nn_getsockopt(nanomsgsrc->main_fd, NN_SOL_SOCKET, NN_RCVFD, (char*)&(nanomsgsrc->watch_fd), &watch_fd_size)) < 0)
	{
		GST_ERROR_OBJECT(nanomsgsrc, "could not retrieve watch file descriptor: %s", strerror(errno));
		goto failure;
	}


	/* Misc settings */

	if (G_UNLIKELY(!gst_nanomsgsrc_update_rcvbufsize(nanomsgsrc, nanomsgsrc->rcvbufsize)))
		goto failure;

	{
		int ipv4only = nanomsgsrc->ipv4only ? 1 : 0;
		if (G_UNLIKELY(nn_setsockopt(nanomsgsrc->main_fd, NN_SOL_SOCKET, NN_IPV4ONLY, (char const*)&(ipv4only), sizeof(ipv4only))) < 0)
		{
			GST_ERROR_OBJECT(nanomsgsrc, "could not configure IPV4ONLY flag: %s", strerror(errno));
			goto failure;
		}
	}


	/* Make sure flushing is disabled in the beginning */
	nanomsgsrc->flushing = FALSE;


	/* All done */
	GST_DEBUG_OBJECT(nanomsgsrc, "initialized SP socket with URI %s", actual_uri);

	return TRUE;


failure:
	gst_nanomsgsrc_shutdown_sockets(nanomsgsrc);
	return FALSE;
}
Exemplo n.º 17
0
JNIEXPORT jint JNICALL Java_org_nanomsg_NanoLibrary_nn_1getsockopt_1int(JNIEnv* env,
                                                                        jobject obj,
                                                                        jint socket,
                                                                        jint level,
                                                                        jint optidx,
                                                                        jobject optval)
{
    jint ret = -1;
    int go = 0;

    switch (level) {
    case NN_SOL_SOCKET:
        switch (optidx) {
        case NN_DOMAIN:
        case NN_PROTOCOL:
        case NN_LINGER:
        case NN_SNDBUF:
        case NN_RCVBUF:
        case NN_SNDTIMEO:
        case NN_RCVTIMEO:
        case NN_RECONNECT_IVL:
        case NN_RECONNECT_IVL_MAX:
        case NN_SNDPRIO:
        case NN_SNDFD:
        case NN_RCVFD:
            go = 1;
            break;
        }
        break;

    case NN_TCP:
        switch (optidx) {
        case NN_TCP_NODELAY:
            go = 1;
            break;
        }
        break;
    }

    if (go) {
        int oval = 0;
        size_t olen = sizeof(oval);

        ret = nn_getsockopt(socket, level, optidx, &oval, &olen);
        if (ret >= 0) {
            jclass cval = 0;
            jfieldID ival = 0;

            ret = olen;

            cval = (*env)->GetObjectClass(env, optval);
            NANO_ASSERT(cval);

            ival = (*env)->GetFieldID(env, cval, "value", "I");
            NANO_ASSERT(ival);

            (*env)->SetIntField(env, optval, ival, oval);
        }
    }

    return ret;
}
Exemplo n.º 18
0
int main (int argc, const char *argv[])
{
    int rc;
    int sb;
    int i;
    int opt;
    size_t sz;
    int s1, s2;
    void * dummy_buf;
    char addr[128];
    char socket_address[128];

    int port = get_test_port(argc, argv);

    test_addr_from(socket_address, "tcp", "127.0.0.1", port);

    /*  Try closing bound but unconnected socket. */
    sb = test_socket (AF_SP, NN_PAIR);
    test_bind (sb, socket_address);
    test_close (sb);

    /*  Try closing a TCP socket while it not connected. At the same time
        test specifying the local address for the connection. */
    sc = test_socket (AF_SP, NN_PAIR);
    test_addr_from(addr, "tcp", "127.0.0.1;127.0.0.1", port);
    test_connect (sc, addr);
    test_close (sc);

    /*  Open the socket anew. */
    sc = test_socket (AF_SP, NN_PAIR);

    /*  Check NODELAY socket option. */
    sz = sizeof (opt);
    rc = nn_getsockopt (sc, NN_TCP, NN_TCP_NODELAY, &opt, &sz);
    errno_assert (rc == 0);
    nn_assert (sz == sizeof (opt));
    nn_assert (opt == 0);
    opt = 2;
    rc = nn_setsockopt (sc, NN_TCP, NN_TCP_NODELAY, &opt, sizeof (opt));
    nn_assert (rc < 0 && nn_errno () == EINVAL);
    opt = 1;
    rc = nn_setsockopt (sc, NN_TCP, NN_TCP_NODELAY, &opt, sizeof (opt));
    errno_assert (rc == 0);
    sz = sizeof (opt);
    rc = nn_getsockopt (sc, NN_TCP, NN_TCP_NODELAY, &opt, &sz);
    errno_assert (rc == 0);
    nn_assert (sz == sizeof (opt));
    nn_assert (opt == 1);

    /*  Try using invalid address strings. */
    rc = nn_connect (sc, "tcp://*:");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_connect (sc, "tcp://*:1000000");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_connect (sc, "tcp://*:some_port");
    nn_assert (rc < 0);
    rc = nn_connect (sc, "tcp://eth10000;127.0.0.1:5555");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == ENODEV);
    rc = nn_connect (sc, "tcp://127.0.0.1");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_bind (sc, "tcp://127.0.0.1:");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_bind (sc, "tcp://127.0.0.1:1000000");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_bind (sc, "tcp://eth10000:5555");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == ENODEV);
    rc = nn_connect (sc, "tcp://:5555");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_connect (sc, "tcp://-hostname:5555");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_connect (sc, "tcp://abc.123.---.#:5555");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_connect (sc, "tcp://[::1]:5555");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_connect (sc, "tcp://abc.123.:5555");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_connect (sc, "tcp://abc...123:5555");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_connect (sc, "tcp://.123:5555");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);

    /*  Connect correctly. Do so before binding the peer socket. */
    test_connect (sc, socket_address);

    /*  Leave enough time for at least on re-connect attempt. */
    nn_sleep (200);

    sb = test_socket (AF_SP, NN_PAIR);
    test_bind (sb, socket_address);

    /*  Ping-pong test. */
    for (i = 0; i != 100; ++i) {

        test_send (sc, "ABC");
        test_recv (sb, "ABC");

        test_send (sb, "DEF");
        test_recv (sc, "DEF");
    }

    /*  Batch transfer test. */
    for (i = 0; i != 100; ++i) {
        test_send (sc, "0123456789012345678901234567890123456789");
    }
    for (i = 0; i != 100; ++i) {
        test_recv (sb, "0123456789012345678901234567890123456789");
    }

    test_close (sc);
    test_close (sb);

    /*  Test whether connection rejection is handled decently. */
    sb = test_socket (AF_SP, NN_PAIR);
    test_bind (sb, socket_address);
    s1 = test_socket (AF_SP, NN_PAIR);
    test_connect (s1, socket_address);
    s2 = test_socket (AF_SP, NN_PAIR);
    test_connect (s2, socket_address);
    nn_sleep (100);
    test_close (s2);
    test_close (s1);
    test_close (sb);

    /*  Test two sockets binding to the same address. */
    sb = test_socket (AF_SP, NN_PAIR);
    test_bind (sb, socket_address);
    s1 = test_socket (AF_SP, NN_PAIR);

    rc = nn_bind (s1, socket_address);
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EADDRINUSE);

    sc = test_socket (AF_SP, NN_PAIR);
    test_connect (sc, socket_address);
    nn_sleep (100);
    test_send (sb, "ABC");
    test_recv (sc, "ABC");
    test_close (sb);
    test_close (sc);
    test_close (s1);

    /*  Test NN_RCVMAXSIZE limit */
    sb = test_socket (AF_SP, NN_PAIR);
    test_bind (sb, socket_address);
    s1 = test_socket (AF_SP, NN_PAIR);
    test_connect (s1, socket_address);
    opt = 4;
    rc = nn_setsockopt (sb, NN_SOL_SOCKET, NN_RCVMAXSIZE, &opt, sizeof (opt));
    nn_assert (rc == 0);
    nn_sleep (100);
    test_send (s1, "ABC");
    test_recv (sb, "ABC");
    test_send (s1, "0123456789012345678901234567890123456789");
    rc = nn_recv (sb, &dummy_buf, NN_MSG, NN_DONTWAIT);
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EAGAIN);
    test_close (sb);
    test_close (s1);

    /*  Test that NN_RCVMAXSIZE can be -1, but not lower */
    sb = test_socket (AF_SP, NN_PAIR);
    opt = -1;
    rc = nn_setsockopt (sb, NN_SOL_SOCKET, NN_RCVMAXSIZE, &opt, sizeof (opt));
    nn_assert (rc >= 0);
    opt = -2;
    rc = nn_setsockopt (sb, NN_SOL_SOCKET, NN_RCVMAXSIZE, &opt, sizeof (opt));
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    test_close (sb);

    /*  Test closing a socket that is waiting to connect. */
    sc = test_socket (AF_SP, NN_PAIR);
    test_connect (sc, socket_address);
    nn_sleep (100);
    test_close (sc);

    return 0;
}
Exemplo n.º 19
0
Arquivo: tcp.c Projeto: Droppe/nanomsg
int main ()
{
    int rc;
    int sb;
    int sc;
    int i;
    char buf [3];
    int opt;
    size_t sz;

    /*  Try closing bound but unconnected socket. */
#if 0
    sb = nn_socket (AF_SP, NN_PAIR);
    errno_assert (sb >= 0);
    rc = nn_bind (sb, SOCKET_ADDRESS);
    errno_assert (rc > 0);
    rc = nn_close (sb);
    errno_assert (rc == 0);
#endif

    /*  Try closing a TCP socket while it not connected. At the same time
        test specifying the local address for connection. */
    sc = nn_socket (AF_SP, NN_PAIR);
    errno_assert (sc != -1);
    rc = nn_connect (sc, "tcp://127.0.0.1;127.0.0.1:5555");
    errno_assert (rc >= 0);
    rc = nn_close (sc);
    errno_assert (rc == 0);

    /*  Open the socket anew. */
    sc = nn_socket (AF_SP, NN_PAIR);
    errno_assert (sc != -1);

    /*  Check NODELAY socket option. */
    sz = sizeof (opt);
    rc = nn_getsockopt (sc, NN_TCP, NN_TCP_NODELAY, &opt, &sz);
    errno_assert (rc == 0);
    nn_assert (sz == sizeof (opt));
    nn_assert (opt == 0);
    opt = 2;
    rc = nn_setsockopt (sc, NN_TCP, NN_TCP_NODELAY, &opt, sizeof (opt));
    nn_assert (rc < 0 && nn_errno () == EINVAL);
    opt = 1;
    rc = nn_setsockopt (sc, NN_TCP, NN_TCP_NODELAY, &opt, sizeof (opt));
    errno_assert (rc == 0);
    sz = sizeof (opt);
    rc = nn_getsockopt (sc, NN_TCP, NN_TCP_NODELAY, &opt, &sz);
    errno_assert (rc == 0);
    nn_assert (sz == sizeof (opt));
    nn_assert (opt == 1);

    /*  Try using invalid address strings. */
    rc = nn_connect (sc, "tcp://*:");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_connect (sc, "tcp://*:1000000");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_connect (sc, "tcp://*:some_port");
    nn_assert (rc < 0);
    rc = nn_connect (sc, "tcp://eth10000;127.0.0.1:5555");
    nn_assert (rc < 0);    
    errno_assert (nn_errno () == ENODEV);
    rc = nn_bind (sc, "tcp://127.0.0.1:");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_bind (sc, "tcp://127.0.0.1:1000000");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == EINVAL);
    rc = nn_bind (sc, "tcp://eth10000:5555");
    nn_assert (rc < 0);
    errno_assert (nn_errno () == ENODEV);

    /*  Connect correctly. Do so before binding the peer socket. */
    rc = nn_connect (sc, SOCKET_ADDRESS);
    errno_assert (rc >= 0);

    /*  Leave enough time for at least on re-connect attempt. */
    nn_sleep (200);

    sb = nn_socket (AF_SP, NN_PAIR);
    errno_assert (sb != -1);
    rc = nn_bind (sb, SOCKET_ADDRESS);
    errno_assert (rc >= 0);

    /*  Ping-pong test. */
    for (i = 0; i != 100; ++i) {

        rc = nn_send (sc, "ABC", 3, 0);
        errno_assert (rc >= 0);
        nn_assert (rc == 3);

        rc = nn_recv (sb, buf, sizeof (buf), 0);
        errno_assert (rc >= 0);
        nn_assert (rc == 3);

        rc = nn_send (sb, "DEF", 3, 0);
        errno_assert (rc >= 0);
        nn_assert (rc == 3);

        rc = nn_recv (sc, buf, sizeof (buf), 0);
        errno_assert (rc >= 0);
        nn_assert (rc == 3);
    }

    /*  Batch transfer test. */
    for (i = 0; i != 100; ++i) {
        rc = nn_send (sc, "0123456789012345678901234567890123456789", 40, 0);
        errno_assert (rc >= 0);
        nn_assert (rc == 40);
    }
    for (i = 0; i != 100; ++i) {
        rc = nn_recv (sb, buf, sizeof (buf), 0);
        errno_assert (rc >= 0);
        nn_assert (rc == 40);
    }

    rc = nn_close (sc);
    errno_assert (rc == 0);
    rc = nn_close (sb);
    errno_assert (rc == 0);

    return 0;
}