/** * main_server_native - it handles the functionality of the client-native * @param socktype the type of socket * @param port_name the prot number * * @return 1 with success, 0 otherwise. */ int main_server_native(int socktype, char *port_name, char *name) { struct endpointinfo hints, *res = NULL; struct sockaddr_eid peer_eid; struct sockaddr_hip our_sockaddr, peer_sock; char mylovemostdata[IP_MAXPACKET]; int recvnum, sendnum, serversock = 0, sockfd = 0, err = 0, on = 1; int endpoint_family = PF_HIP; socklen_t peer_eid_len = sizeof(struct sockaddr_hip); /* recvmsg() stuff for UDP multihoming */ char control[CMSG_SPACE(40)]; struct cmsghdr *cmsg; struct inet6_pktinfo *pktinfo; struct iovec iov = { &mylovemostdata, sizeof(mylovemostdata) - 1 }; struct msghdr msg = { &peer_sock, sizeof(peer_sock), &iov, 1, &control, sizeof(control), 0 }; serversock = socket(endpoint_family, socktype, 0); if (serversock < 0) { HIP_PERROR("socket: "); err = 1; goto out_err; } setsockopt(serversock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); if (socktype == SOCK_DGRAM) setsockopt(serversock, IPPROTO_IPV6, IPV6_2292PKTINFO, &on, sizeof(on)); memset(&hints, 0, sizeof(struct endpointinfo)); hints.ei_family = endpoint_family; hints.ei_socktype = socktype; HIP_DEBUG("Native server calls getendpointinfo\n"); err = getendpointinfo(NULL, port_name, &hints, &res); if (err || !res) { HIP_ERROR("Resolving of peer identifiers failed (%d)\n", err); goto out_err; } memset(&our_sockaddr, 0, sizeof(struct sockaddr_hip)); if (name) { HIP_IFEL(inet_pton(AF_INET6, name, &our_sockaddr.ship_hit) != 1, 1, "Failed to parse HIT\n"); } our_sockaddr.ship_port = htons(atoi(port_name)); HIP_DEBUG("Binding to port %d\n", ntohs(our_sockaddr.ship_port)); our_sockaddr.ship_family = endpoint_family; if (bind(serversock, &our_sockaddr, sizeof(struct sockaddr_hip)) < 0) { HIP_PERROR("bind: "); err = 1; goto out_err; } HIP_DEBUG("Native server calls listen\n"); if (socktype == SOCK_STREAM && listen(serversock, 1) < 0) { HIP_PERROR("listen: "); err = 1; goto out_err; } HIP_DEBUG("Native server waits connection request\n"); while(1) { if (socktype == SOCK_STREAM) { sockfd = accept(serversock, (struct sockaddr *) &peer_sock, &peer_eid_len); if (sockfd < 0) { HIP_PERROR("accept: "); err = 1; goto out_err; } while((recvnum = recv(sockfd, mylovemostdata, sizeof(mylovemostdata), 0)) > 0 ) { mylovemostdata[recvnum] = '\0'; printf("%s", mylovemostdata); fflush(stdout); sendnum = send(sockfd, mylovemostdata, recvnum, 0); if (sendnum < 0) { HIP_PERROR("send: "); err = 1; goto out_err; } } } else { /* UDP */ sockfd = serversock; serversock = 0; while((recvnum = recvmsg(sockfd, &msg, 0)) > 0) { for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_2292PKTINFO) { pktinfo = CMSG_DATA(cmsg); break; } } HIP_DEBUG_HIT("localaddr", &pktinfo->ipi6_addr); iov.iov_len = strlen(mylovemostdata); /* ancillary data contains the src * and dst addresses */ sendnum = sendmsg(sockfd, &msg, 0); if (sendnum < 0) { HIP_PERROR("sendto: "); err = 1; goto out_err; } } } } out_err: if (res) free_endpointinfo(res); if (sockfd) close(sockfd); // discard errors if (serversock) close(serversock); // discard errors return err; }
int main(int argc,char *argv[]) { struct endpointinfo hints, *epinfo, *res = NULL; struct sockaddr_ed *my_ed = NULL; struct timeval stats_before, stats_after; unsigned long stats_diff_sec, stats_diff_usec; char mylovemostdata[IP_MAXPACKET]; char receiveddata[IP_MAXPACKET]; char *proto_name, *peer_port_name, *peer_name; int recvnum, sendnum; int datalen = 0; int proto; int datasent = 0; int datareceived = 0; int ch; int err = 0; int sockfd = 0, socktype; struct se_family_t endpoint_family; char *user_key_base = "/etc/hip/hip_host_dsa_key"; struct endpoint *endpoint; if (argc != 4) { printf("Usage: %s host tcp|udp port\n", argv[0]); err = 1; goto out; } peer_name = argv[1]; proto_name = argv[2]; peer_port_name = argv[3]; endpoint_family = PF_HIP; /* Set transport protocol */ if (strcmp(proto_name, "tcp") == 0) { proto = IPPROTO_TCP; socktype = SOCK_STREAM; } else if (strcmp(proto_name, "udp") == 0) { proto = IPPROTO_UDP; socktype = SOCK_DGRAM; } else { printf("Error: only TCP and UDP supported.\n"); err = 1; goto out; } sockfd = socket(endpoint_family, socktype, 0); if (sockfd == -1) { printf("creation of socket failed\n"); err = 1; goto out; } err = load_hip_endpoint_pem(user_key_base, &endpoint); if (err) { printf("Failed to load user HIP key %s\n", user_key_base); goto out; } my_ed = getlocaled(endpoint, NULL, NULL, NULL); if (!my_ed) { printf("Failed to set up my ED (%d)\n"); err = 1; goto out; } /* We have to bind to the ED to use it. */ err = bind(sockfd, (struct sockaddr *) &my_ed, sizeof(struct sockaddr_ed)); if (err) { perror("bind failed"); goto out; } /* set up endpoint lookup information */ memset(&hints, 0, sizeof(struct endpointinfo)); hints.ei_socktype = socktype; hints.ei_family = endpoint_family; /* Lookup endpoint. We do not need to call getpeered because getendpointinfo does it automatically. */ err = getendpointinfo(peer_name, peer_port_name, &hints, &res); if (err) { printf("getendpointinfo failed (%d): %s\n", err, gepi_strerror(err)); goto out; } printf("family=%d value=%d\n", res->ei_family, ntohs(((struct sockaddr_ed *) res->ei_endpoint)->ed_val)); // data from stdin to buffer bzero(receiveddata, IP_MAXPACKET); bzero(mylovemostdata, IP_MAXPACKET); printf("Input some text, press enter and ctrl+d\n"); // horrible code while ((ch = fgetc(stdin)) != EOF && (datalen < IP_MAXPACKET)) { mylovemostdata[datalen] = (unsigned char) ch; datalen++; } gettimeofday(&stats_before, NULL); epinfo = res; while(epinfo) { err = connect(sockfd, res->ei_endpoint, res->ei_endpointlen); if (err) { perror("connect"); goto out; } epinfo = epinfo->ei_next; } gettimeofday(&stats_after, NULL); stats_diff_sec = (stats_after.tv_sec - stats_before.tv_sec) * 1000000; stats_diff_usec = stats_after.tv_usec - stats_before.tv_usec; printf("connect took %.10f sec\n", (stats_diff_sec + stats_diff_usec) / 1000000.0); /* Send the data read from stdin to the server and read the response. The server should echo all the data received back to here. */ while((datasent < datalen) || (datareceived < datalen)) { if (datasent < datalen) { sendnum = send(sockfd, mylovemostdata + datasent, datalen - datasent, 0); if (sendnum < 0) { perror("send"); err = 1; goto out; } datasent += sendnum; } if (datareceived < datalen) { recvnum = recv(sockfd, receiveddata + datareceived, datalen-datareceived, 0); if (recvnum <= 0) { perror("recv"); err = 1; goto out; } datareceived += recvnum; } } if (memcmp(mylovemostdata, receiveddata, IP_MAXPACKET)) { printf("Sent and received data did not match\n"); err = 1; goto out; } out: if (sockfd) close(sockfd); // discard errors if (res) free_endpointinfo(res); if (my_ed) free(my_ed); printf("Result of data transfer: %s.\n", (err ? "FAIL" : "OK")); return err; }