void test_socket_transfer(void) { int sock_pair[2]; int bound_pair[2]; int rc; int fd1; int fd2; char buf[100]; int received_fds[8]; int received_fd_count; int received_bytes; make_socket_pair(sock_pair); printf("Test data-only messages...\n"); check_send_and_receive_data(sock_pair[0], sock_pair[1]); check_send_and_receive_data(sock_pair[1], sock_pair[0]); rc = imc_makeboundsock(bound_pair); assert(rc == 0); printf("Test sending a BoundSocket (this is rejected)...\n"); rc = send_message(sock_pair[0], test_message, strlen(test_message), &bound_pair[0], 1); assert(rc == -1); assert(errno == EIO); printf("Test sending a ConnectedSocket (this is rejected)...\n"); send_message(sock_pair[0], test_message, strlen(test_message), &sock_pair[0], 1); assert(rc == -1); assert(errno == EIO); printf("Test sending a SocketAddress...\n"); rc = send_message(sock_pair[0], test_message, strlen(test_message), &bound_pair[1], 1); assert(rc == strlen(test_message)); printf("Check that we can receive the SocketAddress we sent...\n"); received_bytes = receive_message(sock_pair[1], buf, sizeof(buf), received_fds, 8, &received_fd_count); assert(received_bytes == strlen(test_message)); assert(memcmp(buf, test_message, strlen(test_message)) == 0); assert(received_fd_count == 1); printf("Check that the received SocketAddress works...\n"); connect_and_accept(bound_pair[0], received_fds[0], &fd1, &fd2); checked_close(received_fds[0]); check_send_and_receive_data(fd1, fd2); check_send_and_receive_data(fd2, fd1); checked_close(fd1); checked_close(fd2); checked_close(sock_pair[0]); checked_close(sock_pair[1]); checked_close(bound_pair[0]); checked_close(bound_pair[1]); }
/* Making a pair of ConnectedSockets is relatively convoluted, since we have to create them via a BoundSocket/SocketAddress pair. */ void make_socket_pair(int pair[2]) { int bound_pair[2]; int rc; rc = imc_makeboundsock(bound_pair); assert(rc == 0); connect_and_accept(bound_pair[0], bound_pair[1], &pair[0], &pair[1]); checked_close(bound_pair[0]); checked_close(bound_pair[1]); }
void test_imc_connect_with_no_acceptor(void) { int bound_pair[2]; int rc; rc = imc_makeboundsock(bound_pair); assert(rc == 0); printf("Test imc_connect() when BoundSocket has been dropped...\n"); checked_close(bound_pair[0]); rc = imc_connect(bound_pair[1]); assert(rc == -1); assert(errno == EIO); checked_close(bound_pair[1]); }
void test_imc_accept_end_of_stream(void) { int bound_pair[2]; int rc; rc = imc_makeboundsock(bound_pair); assert(rc == 0); printf("Test imc_accept() when SocketAddress has been dropped...\n"); checked_close(bound_pair[1]); rc = imc_accept(bound_pair[0]); assert(rc == -1); assert(errno == EIO); checked_close(bound_pair[0]); }
int main(int ac, char **av) { int opt; char const *message = NULL; char const *message2 = NULL; int server = 0; int client_desc = -1; int channel; int sockaddrd; /* socket address descriptor */ int subchannel; int rv; char data_buffer[4096]; int desc_buffer[NACL_ABI_IMC_USER_DESC_MAX]; size_t i; unsigned long loop_iter = 1; unsigned int sleep_seconds = 0; while (EOF != (opt = getopt(ac, av, "c:l:m:M:sS:t:v"))) { switch (opt) { case 'c': client_desc = strtol(optarg, (char **) 0, 0); /* descriptor holds a connection capability for the server */ break; case 'l': loop_iter = strtoul(optarg, (char **) 0, 0); break; case 'm': message = optarg; break; case 'M': message2 = optarg; break; case 's': server = 1; break; case 'S': sleep_seconds = strtoul(optarg, (char **) 0, 0); break; default: fprintf(stderr, ("Usage: sel_ldr [sel_ldr_args] -- " /* no newline */ "nrd_xfer_test2.nexe [-c server-addr-desc] [-s]\n" " [-l loop_count] [-S server-sleep-sec]\n" "\n" "Typically, server is run using a command such as\n" "\n" " sel_ldr -X -1 -D 1 -f nrd_xfer_test2.nexe -- -s\n" "\n" "so the socket address is printed to standard output,\n" "and then the client is run with a command such as\n" "\n" " sel_ldr -X -1 -a 6:<addr-from-server> " /* no \n */ "-- nrd_xfer_test_nacl.nexe -c 6\n" "\n" "to have descriptor 6 be used to represent the socket\n" "address for connecting to the server\n")); return 1; } } for (i = 0; i < sizeof desc_buffer / sizeof desc_buffer[0]; ++i) { desc_buffer[i] = -1; } if (server) { message = (NULL != message) ? message : "\"Hello world!\", from server\n"; message2 = (NULL != message2) ? message2 : "SERVER MSG2"; } else { message = (NULL != message) ? message : "Client connect request\n"; message2 = (NULL != message2) ? message2 :"\"Goodbye cruel world!\", from client\n"; } if (server) { int pair[2]; pthread_t thr; int err; printf("Accepting a client connection...\n"); channel = imc_accept(3); printf("...got channel descriptor %d\n", channel); do { rv = recv_imc_msg(channel, data_buffer, sizeof data_buffer, NULL); printf("Receive returned %d\n", rv); if (-1 == rv) { fprintf(stderr, "imc_recvmsg failed\n"); return 1; } printf("Data bytes: %.*s\n", rv, data_buffer); /* send a reply */ if (-1 == imc_makeboundsock(pair)) { fprintf(stderr, "imc_socketpair failed, errno %d\n", errno); return 2; } /* * send pair[1], the addr, to peer as reply. */ send_imc_msg(channel, "sockaddr", pair[1]); err = pthread_create(&thr, NULL, worker_thread, (void *) pair[0]); if (0 != err) { fprintf(stderr, "pthread_create failed, returned %d\n", err); return 4; } pthread_detach(thr); if (-1 == close(pair[1])) { fprintf(stderr, "close of socketpair half failed\n"); } if (0 != sleep_seconds) { printf("sleeping for %d seconds...\n", sleep_seconds); sleep(sleep_seconds); } } while (--loop_iter > 0); if (-1 == close(channel)) { fprintf(stderr, "close of channel %d failed\n", channel); } } else { if (-1 == client_desc) { fprintf(stderr, "Client needs server socket address to which to connect\n"); return 100; } channel = imc_connect(client_desc); printf("Connect returned %d\n", channel); if (-1 == channel) { fprintf(stderr, "Client could not connect, errno %d\n", errno); return 101; } do { send_imc_msg(channel, message, -1); rv = recv_imc_msg(channel, data_buffer, sizeof data_buffer, &sockaddrd); printf("start RPC reply returned socket addr desc %d\n", sockaddrd); if (-1 == sockaddrd) { fprintf(stderr, "connect failed, errno %d\n", errno); return 106; } subchannel = imc_connect(sockaddrd); if (-1 == subchannel) { printf("Connect for client-specific socket failed: errno %d\n", errno); return 107; } if (-1 == close(sockaddrd)) { fprintf(stderr, "close of %d sockaddr failed, errno %d\n", sockaddrd, errno); } send_imc_msg(subchannel, message2, -1); if (-1 == (rv = recv_imc_msg(subchannel, data_buffer, sizeof data_buffer, NULL))) { fprintf(stderr, "receive from worker thread failed, errno %d\n", errno); return 108; } /* let's not trust server to NUL terminate */ data_buffer[sizeof data_buffer - 1] = '\0'; printf("reply: %s\n", data_buffer); if (-1 == close(subchannel)) { fprintf(stderr, "close of subchannel %d failed\n", subchannel); } } while (--loop_iter > 0); if (-1 == close(channel)) { fprintf(stderr, "close of %d (channel) failed\n", channel); } } return 0; }