Ejemplo n.º 1
0
/**
 * handle_hit_value - This function copies the hit returned from the lookup service
 *
 * @param *packet response returned from the lookup service
 * @param *hit opaque pointer passed to point to the HIT
 * @return status of the operation 0 on success, -1 on failure
 */
int handle_hit_value (unsigned char *packet, void *hit)
{
	if (ipv6_addr_is_hit((struct in6_addr*)packet)) {
		hip_in6_ntop((struct in6_addr *)packet, (char*)hit);
		return 0 ;
	} else 
		return -1 ;
}
Ejemplo n.º 2
0
/**
 * Creates a socket and connects it a remote socket address. The connection is
 * tried using addresses in the @c peer_ai in the order specified by the linked
 * list of the structure. If a connection is successful, the rest of the
 * addresses are omitted. The socket is bound to the peer HIT, not to the peer
 * IP addresses.
 *
 * @param peer_ai a pointer to peer address info.
 * @param sock    a target buffer where the socket file descriptor is to be
 *                stored.
 * @return        zero on success, negative on failure. Possible error values
 *                are the @c errno values of socket(), connect() and close()
 *                with a minus sign.
 */
int hip_connect_func(struct addrinfo *peer_ai, int *sock)
{
	int err = 0, connect_err = 0;
	unsigned long microseconds = 0;
	struct timeval stats_before, stats_after;
	char ip_str[INET6_ADDRSTRLEN];
	struct addrinfo *ai = NULL;
	struct in_addr *ipv4 = NULL;
	struct in6_addr *ipv6 = NULL;

	/* Set the memory allocated from the stack to zeros. */
	memset(&stats_before, 0, sizeof(stats_before));
	memset(&stats_after, 0, sizeof(stats_after));
	memset(ip_str, 0, sizeof(ip_str));
	
	/* Loop through every address in the address info. */
	for(ai = peer_ai; ai != NULL; ai = ai->ai_next) {
	        if (ai->ai_family == AF_INET)
		  _HIP_DEBUG("AF_INET\n");
		else
		  _HIP_DEBUG("af_inet6\n");
	}
	for(ai = peer_ai; ai != NULL; ai = ai->ai_next) {
	        ipv4 = &((struct sockaddr_in *)ai->ai_addr)->sin_addr;
		ipv6 = &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr;

		/* Check the type of address we are connecting to and print
		   information about the address to the user. If address is
		   not supported the move to next address in peer_ai. */
		if (ai->ai_family == AF_INET) {
			inet_ntop(AF_INET, ipv4, ip_str, sizeof(ip_str));
			
			if(IS_LSI32(ipv4->s_addr)) {
				HIP_INFO("Connecting to LSI %s.\n", ip_str);
			} else {
				HIP_INFO("Connecting to IPv4 address %s.\n",
					 ip_str);
			}
		} else if(ai->ai_family == AF_INET6 ||
			  ai->ai_family == AF_HIP) {
			inet_ntop(AF_INET6, ipv6, ip_str, sizeof(ip_str));
			
			if(ipv6_addr_is_hit(ipv6)){
				HIP_INFO("Connecting to HIT %s.\n", ip_str);
			} else if (IN6_IS_ADDR_V4MAPPED(ipv6)) {
				HIP_INFO("Connecting to IPv6-mapped IPv4 "\
					 "address %s.\n", ip_str);
			} else {
				HIP_INFO("Connecting to IPv6 address %s.\n",
					 ip_str);
			}
		} else {
			_HIP_DEBUG("Trying to connect to a non-inet address "\
				  "family address. Skipping.\n");
			/* If there are no more address in peer_ai, these err
			   and errno values are returned. */
			errno = EAFNOSUPPORT;
			err = -1;
			continue;
		}

		err = 0;
		errno = 0;
		
		/* Get a socket for sending. */
		*sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);

		if(*sock < 3) {
			HIP_ERROR("Unable to get a socket for sending.\n");
			err = -1;
			goto out_err;
		}
		
		gettimeofday(&stats_before, NULL);
		connect_err = connect(*sock, ai->ai_addr, ai->ai_addrlen);
		
		/* If we're unable to connect to the remote address we try next
		   address in peer_ai. We back off if the closing of the socket
		   fails. */
		if(connect_err != 0){
			_HIP_ERROR("Unable to connect to the remote address.\n");
			if(close(*sock) != 0) {
				HIP_ERROR("Unable to close a socket.\n");
				err = -1;
				break;
			}
			*sock = 0;
			err = -1;
			continue;
		}
	
		gettimeofday(&stats_after, NULL);
		
		microseconds  =
			((stats_after.tv_sec - stats_before.tv_sec) * 1000000)
			+ (stats_after.tv_usec - stats_before.tv_usec);
		
		printf("Connecting socket to remote socket address took "\
		       "%.5f seconds.\n", microseconds / 1000000.0 );
		
		if (connect_err != 0) {
			if(close(*sock) != 0) {
				HIP_ERROR("Unable to close a socket.\n");
				err = -1;
				break;
			}
			*sock = 0;
			/* Try the next address in peer_ai. */
			continue;
		} else {
			/* Connect succeeded and data can be sent/received. */
			break;
		}
	}
		
 out_err:
	return err;
}