LONGBOW_TEST_CASE(Global, cpiAddress_ToString_INET) { struct sockaddr_in *addr_in = parcNetwork_SockInet4Address("1.2.3.4", 12345); char expected[] = "inet4://1.2.3.4:12345"; CPIAddress *cpiaddr = cpiAddress_CreateFromInet(addr_in); char *actual = cpiAddress_ToString(cpiaddr); assertTrue(strcmp(actual, expected) == 0, "Bad string, expected '%s' got '%s'", expected, actual); parcMemory_Deallocate((void **) &actual); cpiAddress_Destroy(&cpiaddr); parcMemory_Deallocate((void **) &addr_in); }
LONGBOW_TEST_CASE(Global, parcNetwork_SockInet4Address_BuildString) { PARCBufferComposer *composer = parcBufferComposer_Create(); struct sockaddr_in *address = parcNetwork_SockInet4Address("127.0.0.1", 1234); #if defined(SIN6_LEN) assertTrue(address->sin_len == sizeof(struct sockaddr_in), "Expecting sockaddr.sin_len to be %zu not %hhu\n", sizeof(struct sockaddr_in), address->sin_len); #endif parcNetwork_SockInet4Address_BuildString(address, composer); char *expected = "inet4://127.0.0.1:1234"; PARCBuffer *tempBuffer = parcBufferComposer_ProduceBuffer(composer); char *actual = parcBuffer_ToString(tempBuffer); parcBuffer_Release(&tempBuffer); assertTrue(strcmp(expected, actual) == 0, "Expected '%s', actual '%s'", expected, actual); parcMemory_Deallocate((void **) &actual); parcMemory_Deallocate((void **) &address); parcBufferComposer_Release(&composer); }
static AthenaTransportLink * _UDPOpen(AthenaTransportLinkModule *athenaTransportLinkModule, PARCURI *connectionURI) { AthenaTransportLink *result = 0; const char *authorityString = parcURI_GetAuthority(connectionURI); if (authorityString == NULL) { parcLog_Error(athenaTransportLinkModule_GetLogger(athenaTransportLinkModule), "Unable to parse connection authority %s", authorityString); errno = EINVAL; return NULL; } PARCURIAuthority *authority = parcURIAuthority_Parse(authorityString); const char *URIAddress = parcURIAuthority_GetHostName(authority); in_port_t port = parcURIAuthority_GetPort(authority); // Normalize the provided hostname struct sockaddr_in *addr = (struct sockaddr_in *) parcNetwork_SockAddress(URIAddress, port); char *address = inet_ntoa(addr->sin_addr); parcMemory_Deallocate(&addr); parcURIAuthority_Release(&authority); if (address == NULL) { parcLog_Error(athenaTransportLinkModule_GetLogger(athenaTransportLinkModule), "Unable to lookup hostname %s", address); errno = EINVAL; return NULL; } if (port == 0) { parcLog_Error(athenaTransportLinkModule_GetLogger(athenaTransportLinkModule), "Invalid address specification, port == 0"); errno = EINVAL; return NULL; } bool listener = false; char name[MAXPATHLEN] = { 0 }; char srcAddress[NI_MAXHOST] = "0.0.0.0"; size_t mtu = 0; uint16_t srcPort = 0; char localFlag[MAXPATHLEN] = { 0 }; int forceLocal = 0; char *linkName = NULL; PARCURIPath *remainder = parcURI_GetPath(connectionURI); size_t segments = parcURIPath_Count(remainder); for (int i = 0; i < segments; i++) { PARCURISegment *segment = parcURIPath_Get(remainder, i); const char *token = parcURISegment_ToString(segment); if (strcasecmp(token, UDP_LISTENER_FLAG) == 0) { listener = true; parcMemory_Deallocate(&token); continue; } if (strncasecmp(token, SRC_LINK_SPECIFIER, strlen(SRC_LINK_SPECIFIER)) == 0) { if (sscanf(token, "%*[^%%]%%3D%[^%%]%%3A%hd", srcAddress, &srcPort) != 2) { parcLog_Error(athenaTransportLinkModule_GetLogger(athenaTransportLinkModule), "Improper connection source specification (%s)", token); parcMemory_Deallocate(&token); errno = EINVAL; return NULL; } // Normalize the provided hostname struct sockaddr_in *addr = (struct sockaddr_in *) parcNetwork_SockAddress(srcAddress, srcPort); char *hostname = inet_ntoa(addr->sin_addr); parcMemory_Deallocate(&addr); memcpy(srcAddress, hostname, strlen(hostname) + 1); parcMemory_Deallocate(&token); continue; } if (strncasecmp(token, LINK_MTU_SIZE, strlen(LINK_MTU_SIZE)) == 0) { if (sscanf(token, "%*[^%%]%%3D%zd", &mtu) != 1) { parcLog_Error(athenaTransportLinkModule_GetLogger(athenaTransportLinkModule), "Improper MTU specification (%s)", token); parcMemory_Deallocate(&token); errno = EINVAL; return NULL; } parcMemory_Deallocate(&token); continue; } if (strncasecmp(token, LINK_NAME_SPECIFIER, strlen(LINK_NAME_SPECIFIER)) == 0) { if (sscanf(token, "%*[^%%]%%3D%s", name) != 1) { parcLog_Error(athenaTransportLinkModule_GetLogger(athenaTransportLinkModule), "Improper connection name specification (%s)", token); parcMemory_Deallocate(&token); errno = EINVAL; return NULL; } linkName = name; parcMemory_Deallocate(&token); continue; } if (strncasecmp(token, LOCAL_LINK_FLAG, strlen(LOCAL_LINK_FLAG)) == 0) { if (sscanf(token, "%*[^%%]%%3D%s", localFlag) != 1) { parcLog_Error(athenaTransportLinkModule_GetLogger(athenaTransportLinkModule), "Improper local specification (%s)", token); parcMemory_Deallocate(&token); errno = EINVAL; return NULL; } if (strncasecmp(localFlag, "false", strlen("false")) == 0) { forceLocal = AthenaTransportLink_ForcedNonLocal; } else if (strncasecmp(localFlag, "true", strlen("true")) == 0) { forceLocal = AthenaTransportLink_ForcedLocal; } else { parcLog_Error(athenaTransportLinkModule_GetLogger(athenaTransportLinkModule), "Improper local state specification (%s)", token); parcMemory_Deallocate(&token); errno = EINVAL; return NULL; } parcMemory_Deallocate(&token); continue; } parcLog_Error(athenaTransportLinkModule_GetLogger(athenaTransportLinkModule), "Unknown connection parameter (%s)", token); parcMemory_Deallocate(&token); errno = EINVAL; return NULL; } struct sockaddr_in *destination = parcNetwork_SockInet4Address(address, port); struct sockaddr_in *source = parcNetwork_SockInet4Address(srcAddress, srcPort); if (listener) { result = _UDPOpenListener(athenaTransportLinkModule, linkName, destination, mtu); } else { result = _UDPOpenConnection(athenaTransportLinkModule, linkName, source, destination, mtu); } parcMemory_Deallocate(&destination); parcMemory_Deallocate(&source); // forced IsLocal/IsNotLocal, mainly for testing if (result && forceLocal) { athenaTransportLink_ForceLocal(result, forceLocal); } return result; }