/* * A client writer to test network_client_create. Connects to IPv4 localhost, * and expects to always succeed on the connection, taking the source address * to pass into network_client_create. */ static void client_create_writer(const char *source) { socket_type fd; struct sockaddr_in sin; FILE *out; fd = network_client_create(PF_INET, SOCK_STREAM, source); if (fd == INVALID_SOCKET) _exit(1); memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(11119); sin.sin_addr.s_addr = htonl(0x7f000001UL); if (connect(fd, (struct sockaddr *) &sin, sizeof(sin)) < 0) _exit(1); out = fdopen(fd, "w"); if (out == NULL) _exit(1); fputs("socket test\r\n", out); fclose(out); _exit(0); }
int main(void) { socket_type fd; struct sockaddr_in sin; size_t size; ssize_t result; struct lbcd_reply reply; struct lbcd_request request; /* Declare a plan. */ plan(65); /* Start the lbcd daemon, allowing load and rr services. */ lbcd_start("-a", "load", "-a", "rr", NULL); /* Set up our client socket. */ fd = network_client_create(PF_INET, SOCK_DGRAM, "127.0.0.1"); if (fd == INVALID_SOCKET) sysbail("cannot create client socket"); memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(14330); sin.sin_addr.s_addr = htonl(0x7f000001UL); if (connect(fd, (struct sockaddr *) &sin, sizeof(sin)) < 0) sysbail("cannot connect client socket"); /* Send a simple version three query and get the reply. */ memset(&request, 0, sizeof(request)); request.h.version = htons(3); request.h.id = htons(10); request.h.op = htons(LBCD_OP_LBINFO); result = send(fd, &request, sizeof(struct lbcd_header), 0); if (result != (ssize_t) sizeof(struct lbcd_header)) sysbail("cannot send simple version 3 query"); memset(&reply, 0, sizeof(reply)); result = recv(fd, &reply, sizeof(reply), 0); /* Check that the reply is what we expect. */ is_sane_reply(&request, &reply, result, "simple protocol three query"); /* Send a version two query and get the reply. */ request.h.version = htons(2); request.h.id = htons(20); request.h.status = htons(200); result = send(fd, &request, sizeof(struct lbcd_header), 0); if (result != (ssize_t) sizeof(struct lbcd_header)) sysbail("cannot send version 2 query"); memset(&reply, 0, sizeof(reply)); result = recv(fd, &reply, sizeof(reply), 0); /* Check that the reply is what we expect. */ is_sane_reply(&request, &reply, result, "protocol two query"); /* * Send a more complex version three query with three requested services: * default, which should always be allowed, load, which should match * default, and rr. */ request.h.version = htons(3); request.h.status = htons(3); strlcpy(request.names[0], "default", sizeof(request.names[0])); strlcpy(request.names[1], "load", sizeof(request.names[0])); strlcpy(request.names[2], "rr", sizeof(request.names[0])); size = sizeof(struct lbcd_header) + 3 * sizeof(lbcd_name_type); result = send(fd, &request, size, 0); if (result != (ssize_t) size) sysbail("cannot send complex version 3 query"); memset(&reply, 0, sizeof(reply)); result = recv(fd, &reply, sizeof(reply), 0); /* Check that the reply is what we expect. */ is_sane_reply(&request, &reply, result, "complex protocol three query"); is_int(ntohl(reply.weights[0].host_weight), ntohl(reply.weights[1].host_weight), "...default service weight matches first weight"); is_int(ntohl(reply.weights[0].host_incr), ntohl(reply.weights[1].host_incr), "...default service increment matches first increment"); is_int(ntohl(reply.weights[0].host_weight), ntohl(reply.weights[2].host_weight), "...load service weight matches first weight"); is_int(ntohl(reply.weights[0].host_incr), ntohl(reply.weights[2].host_incr), "...load service increment matches first increment"); is_int(1, ntohl(reply.weights[3].host_weight), "...rr service weight is 1"); is_int(1, ntohl(reply.weights[3].host_incr), "...rr service increment is 1"); /* All done. Clean up and return. */ close(fd); return 0; }