Esempio n. 1
0
/**
 * 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;
}
Esempio n. 2
0
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;
}