static AthenaTransportLink *
_newLink(AthenaTransportLink *athenaTransportLink, _UDPLinkData *newLinkData)
{
    // Accept a new tunnel connection.

    // Clone a new link from the current listener.
    const char *derivedLinkName = _createNameFromLinkData(&newLinkData->link);
    AthenaTransportLink *newTransportLink = athenaTransportLink_Clone(athenaTransportLink,
                                                                      derivedLinkName,
                                                                      _UDPSend,
                                                                      _UDPReceiveProxy,
                                                                      _UDPClose);
    if (newTransportLink == NULL) {
        parcLog_Error(athenaTransportLink_GetLogger(athenaTransportLink),
                      "athenaTransportLink_Clone failed");
        parcMemory_Deallocate(&derivedLinkName);
        _UDPLinkData_Destroy(&newLinkData);
        return NULL;
    }

    _setConnectLinkState(newTransportLink, newLinkData);

    // Send the new link up to be added.
    int result = athenaTransportLink_AddLink(athenaTransportLink, newTransportLink);
    if (result == -1) {
        parcLog_Error(athenaTransportLink_GetLogger(athenaTransportLink),
                      "athenaTransportLink_AddLink failed: %s", strerror(errno));
        _UDPLinkData_Destroy(&newLinkData);
        athenaTransportLink_Release(&newTransportLink);
    } else {
        parcLog_Info(athenaTransportLink_GetLogger(athenaTransportLink),
                     "new link accepted by %s: %s %s",
                     athenaTransportLink_GetName(athenaTransportLink), derivedLinkName,
                     athenaTransportLink_IsNotLocal(athenaTransportLink) ? "" : "(Local)");
    }

    parcMemory_Deallocate(&derivedLinkName);

    // Could pass a message back here regarding the new link.
    return newTransportLink;
}
//
// Open a UDP point to point connection.
//
static AthenaTransportLink *
_UDPOpenConnection(AthenaTransportLinkModule *athenaTransportLinkModule, const char *linkName, struct sockaddr_in *source, struct sockaddr_in *destination, size_t mtu)
{
    const char *derivedLinkName;

    _UDPLinkData *linkData = _UDPLinkData_Create();

    linkData->link.peerAddress = *((struct sockaddr_in *) destination);
    linkData->link.peerAddressLength = sizeof(struct sockaddr_in);
    linkData->link.mtu = mtu;

    linkData->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (linkData->fd < 0) {
        parcLog_Error(athenaTransportLinkModule_GetLogger(athenaTransportLinkModule), "socket error (%s)", strerror(errno));
        _UDPLinkData_Destroy(&linkData);
        return NULL;
    }

    int result = _setSocketOptions(athenaTransportLinkModule, linkData->fd);
    if (result) {
        close(linkData->fd);
        _UDPLinkData_Destroy(&linkData);
        return NULL;
    }

    // bind the local endpoint so we can know our allocated port if it was wildcarded
    result = bind(linkData->fd, (struct sockaddr *) source, sizeof(struct sockaddr_in));
    if (result) {
        parcLog_Error(athenaTransportLinkModule_GetLogger(athenaTransportLinkModule),
                      "bind error (%s)", strerror(errno));
        close(linkData->fd);
        _UDPLinkData_Destroy(&linkData);
        return NULL;
    }

    // Retrieve the local endpoint data, used to create the derived name.
    linkData->link.myAddressLength = sizeof(struct sockaddr_in);
    result = getsockname(linkData->fd, (struct sockaddr *) &linkData->link.myAddress, &linkData->link.myAddressLength);
    if (result != 0) {
        parcLog_Error(athenaTransportLinkModule_GetLogger(athenaTransportLinkModule),
                      "Failed to obtain endpoint information from getsockname.");
        _UDPLinkData_Destroy(&linkData);
        return NULL;
    }

    derivedLinkName = _createNameFromLinkData(&linkData->link);

    if (linkName == NULL) {
        linkName = derivedLinkName;
    }

    AthenaTransportLink *athenaTransportLink = athenaTransportLink_Create(linkName,
                                                                          _UDPSend,
                                                                          _UDPReceive,
                                                                          _UDPClose);
    if (athenaTransportLink == NULL) {
        parcLog_Error(athenaTransportLink_GetLogger(athenaTransportLink),
                      "athenaTransportLink_Create failed");
        parcMemory_Deallocate(&derivedLinkName);
        _UDPLinkData_Destroy(&linkData);
        return NULL;
    }

    _setConnectLinkState(athenaTransportLink, linkData);
    // Enable Send? XXX
    athenaTransportLink_SetEvent(athenaTransportLink, AthenaTransportLinkEvent_Send);

    parcLog_Info(athenaTransportLink_GetLogger(athenaTransportLink),
                 "new link established: Name=\"%s\" (%s)", linkName, derivedLinkName);

    parcMemory_Deallocate(&derivedLinkName);
    return athenaTransportLink;
    return NULL;
}
//
// Open a point to point connection.
//
static AthenaTransportLink *
_ETHOpenConnection(AthenaTransportLinkModule *athenaTransportLinkModule, const char *linkName, const char *device, struct ether_addr *source, struct ether_addr *destination, size_t mtu)
{
    const char *derivedLinkName;

    _ETHLinkData *linkData = _ETHLinkData_Create();

    linkData->athenaEthernet = athenaEthernet_Create(athenaTransportLinkModule_GetLogger(athenaTransportLinkModule),
                                                     device, CCNX_ETHERTYPE);
    if (linkData->athenaEthernet == NULL) {
        _ETHLinkData_Destroy(&linkData);
        return NULL;
    }

    // Use our default MAC address if none specified.
    if (source == NULL) {
        athenaEthernet_GetMAC(linkData->athenaEthernet, &(linkData->link.myAddress));
        linkData->link.myAddressLength = ETHER_ADDR_LEN;
    } else {
        memcpy(&(linkData->link.myAddress), source, sizeof(struct ether_addr));
    }

    // If there's no destination specified, drop the request.
    if (destination == NULL) {
        _ETHLinkData_Destroy(&linkData);
        return NULL;
    }

    // Copy the peer destination address into our link data
    memcpy(&(linkData->link.peerAddress), destination, sizeof(struct ether_addr));

    derivedLinkName = _createNameFromLinkData(&linkData->link, false);

    if (linkName == NULL) {
        linkName = derivedLinkName;
    }

    AthenaTransportLink *athenaTransportLink = athenaTransportLink_Create(linkName,
                                                                          _ETHSend,
                                                                          _ETHReceive,
                                                                          _ETHClose);
    if (athenaTransportLink == NULL) {
        parcLog_Error(athenaTransportLink_GetLogger(athenaTransportLink),
                      "athenaTransportLink_Create failed");
        parcMemory_Deallocate(&derivedLinkName);
        _ETHLinkData_Destroy(&linkData);
        return NULL;
    }

    _setConnectLinkState(athenaTransportLink, linkData);

    // Enable Sends
    athenaTransportLink_SetEvent(athenaTransportLink, AthenaTransportLinkEvent_Send);

    parcLog_Info(athenaTransportLink_GetLogger(athenaTransportLink),
                 "new link established: Name=\"%s\" (%s)", linkName, derivedLinkName);

    parcMemory_Deallocate(&derivedLinkName);
    return athenaTransportLink;
    return NULL;
}