ndn_Error ndn_TcpTransport_isLocal(const char *host, int *result) { // Imitate ndn_SocketTransport_connect to use getaddrinfo. struct addrinfo hints; struct addrinfo *serverInfo; char ipString[INET6_ADDRSTRLEN]; ndn_memset((uint8_t *)&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if (getaddrinfo(host, NULL, &hints, &serverInfo) != 0) return NDN_ERROR_SocketTransport_error_in_getaddrinfo; // Only look at the first serverInfo. if (serverInfo->ai_family == AF_INET) { struct sockaddr_in *ipv4 = (struct sockaddr_in *)serverInfo->ai_addr; inet_ntop(serverInfo->ai_family, &ipv4->sin_addr, ipString, sizeof(ipString)); *result = (ndn_memcmp((const uint8_t *)ipString, (const uint8_t *)"127.", 4) == 0 ? 1 : 0); } else { struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)serverInfo->ai_addr; inet_ntop(serverInfo->ai_family, &ipv6->sin6_addr, ipString, sizeof(ipString)); *result = (strcmp(ipString, "::1") == 0 ? 1 : 0); } freeaddrinfo(serverInfo); return NDN_ERROR_success; }
ndn_Error ndn_SocketTransport_connect (struct ndn_SocketTransport *self, ndn_SocketType socketType, const char *host, unsigned short port, struct ndn_ElementListener *elementListener) { int socketDescriptor; ndn_ElementReader_reset(&self->elementReader, elementListener); if (socketType == SOCKET_UNIX) { struct sockaddr_un address; memset(&address, 0, sizeof(struct sockaddr_un)); if ((socketDescriptor = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) return NDN_ERROR_SocketTransport_cannot_connect_to_socket; address.sun_family = AF_UNIX; strcpy(address.sun_path, host); if (connect(socketDescriptor, (struct sockaddr *)&address, SUN_LEN(&address)) == -1) { close(socketDescriptor); return NDN_ERROR_SocketTransport_cannot_connect_to_socket; } } else { struct addrinfo hints; char portString[10]; struct addrinfo *serverInfo; struct addrinfo *p; if (self->socketDescriptor >= 0) { close(self->socketDescriptor); self->socketDescriptor = -1; } ndn_memset((uint8_t *)&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; if (socketType == SOCKET_TCP) hints.ai_socktype = SOCK_STREAM; else if (socketType == SOCKET_UDP) hints.ai_socktype = SOCK_DGRAM; else return NDN_ERROR_unrecognized_ndn_SocketTransport; sprintf(portString, "%d", port); if (getaddrinfo(host, portString, &hints, &serverInfo) != 0) return NDN_ERROR_SocketTransport_error_in_getaddrinfo; // loop through all the results and connect to the first we can for(p = serverInfo; p != NULL; p = p->ai_next) { if ((socketDescriptor = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) continue; if (connect(socketDescriptor, p->ai_addr, p->ai_addrlen) == -1) { close(socketDescriptor); continue; } break; } if (p == NULL) { freeaddrinfo(serverInfo); return NDN_ERROR_SocketTransport_cannot_connect_to_socket; } freeaddrinfo(serverInfo); } self->socketDescriptor = socketDescriptor; return NDN_ERROR_success; }