/** * 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 ; }
/** * 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; }