diff options
author | Luca Muscariello <lumuscar+fdio@cisco.com> | 2019-03-23 14:13:53 +0100 |
---|---|---|
committer | Angelo Mantellini <manangel@cisco.com> | 2019-03-24 14:11:17 +0100 |
commit | eb323e056e747d71867cf965434811c1de925de2 (patch) | |
tree | 23a6096823d795efe448559cf0409a18ab47932d /hicn-light/src/io/hicnConnection.c | |
parent | 43562f9f02d35e5d540ab4028a0326c0c7cd4898 (diff) |
[HICN-141] Definition of a C API for hicn-light
Change-Id: Id861f0abe58b1e3c9ba8cc76701da0f9c6801748
Signed-off-by: Luca Muscariello <lumuscar+fdio@cisco.com>
Signed-off-by: Angelo Mantellini <manangel@cisco.com>
Diffstat (limited to 'hicn-light/src/io/hicnConnection.c')
-rw-r--r-- | hicn-light/src/io/hicnConnection.c | 524 |
1 files changed, 0 insertions, 524 deletions
diff --git a/hicn-light/src/io/hicnConnection.c b/hicn-light/src/io/hicnConnection.c deleted file mode 100644 index 991c0064e..000000000 --- a/hicn-light/src/io/hicnConnection.c +++ /dev/null @@ -1,524 +0,0 @@ -/* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Embodies the reader/writer for a Hicn connection - * - * NB The Send() function may overflow the output buffer - * - */ - -#include <errno.h> -#include <src/config.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> - -#include <src/core/message.h> -#include <src/io/hicnConnection.h> - -#include <src/core/messageHandler.h> - -#include <parc/algol/parc_Hash.h> -#include <parc/algol/parc_Memory.h> -#include <parc/assert/parc_Assert.h> -#include <src/core/connection.h> -#include <src/core/forwarder.h> - -typedef struct hicn_state { - Forwarder *forwarder; - Logger *logger; - - // the hicn listener socket we receive packets on - int hicnListenerSocket; - - AddressPair *addressPair; - - // We need to access this all the time, so grab it out - // of the addressPair; - struct sockaddr *peerAddress; - socklen_t peerAddressLength; - - struct sockaddr *localAddress; - socklen_t localAddressLength; - - // this address contains one of the content names reachable - // throught the connection peer. We need this address beacuse it is - // the only way we have to conntact the next hop, since the main tun - // does not have address. Notice that a connection that sends probes - // is a connection that sends interest. In a "data" connection this - // value will remain NULL. We refresh the content address every time - // we send a probe, in this way we don't need to waste to much time in - // copy the address, but we can also react to the routing changes - struct sockaddr *probeDestAddress; - socklen_t probeDestAddressLength; - bool refreshProbeDestAddress; - - bool isLocal; - bool isUp; - unsigned id; - - unsigned delay; -} _HicnState; - -// Prototypes -static bool _send(IoOperations *ops, const Address *nexthop, Message *message); -static bool _sendCommandResponse(IoOperations *ops, struct iovec *message); -static const Address *_getRemoteAddress(const IoOperations *ops); -static const AddressPair *_getAddressPair(const IoOperations *ops); -static unsigned _getConnectionId(const IoOperations *ops); -static bool _isUp(const IoOperations *ops); -static bool _isLocal(const IoOperations *ops); -static void _destroy(IoOperations **opsPtr); -static list_connections_type _getConnectionType(const IoOperations *ops); -static Ticks _sendProbe(IoOperations *ops, unsigned probeType, - uint8_t *message); - -/* - * This assigns a unique pointer to the void * which we use - * as a GUID for this class. - */ -static const void *_ioOperationsGuid = __FILE__; - -/* - * Return our GUID - */ -static const void *_streamConnection_Class(const IoOperations *ops) { - return _ioOperationsGuid; -} - -static IoOperations _template = {.closure = NULL, - .send = &_send, - .sendCommandResponse = &_sendCommandResponse, - .getRemoteAddress = &_getRemoteAddress, - .getAddressPair = &_getAddressPair, - .getConnectionId = &_getConnectionId, - .isUp = &_isUp, - .isLocal = &_isLocal, - .destroy = &_destroy, - .class = &_streamConnection_Class, - .getConnectionType = &_getConnectionType, - .sendProbe = &_sendProbe}; - -// ================================================================= - -static void _setConnectionState(_HicnState *Hicn, bool isUp); -static bool _saveSockaddr(_HicnState *hicnConnState, const AddressPair *pair); -static void _refreshProbeDestAddress(_HicnState *hicnConnState, - const uint8_t *message); - -IoOperations *hicnConnection_Create(Forwarder *forwarder, int fd, - const AddressPair *pair, bool isLocal) { - IoOperations *io_ops = NULL; - - _HicnState *hicnConnState = parcMemory_AllocateAndClear(sizeof(_HicnState)); - parcAssertNotNull(hicnConnState, - "parcMemory_AllocateAndClear(%zu) returned NULL", - sizeof(_HicnState)); - - hicnConnState->forwarder = forwarder; - hicnConnState->logger = logger_Acquire(forwarder_GetLogger(forwarder)); - - bool saved = _saveSockaddr(hicnConnState, pair); - if (saved) { - hicnConnState->hicnListenerSocket = fd; - hicnConnState->id = forwarder_GetNextConnectionId(forwarder); - hicnConnState->addressPair = addressPair_Acquire(pair); - hicnConnState->isLocal = isLocal; - - // allocate a connection - io_ops = parcMemory_AllocateAndClear(sizeof(IoOperations)); - parcAssertNotNull(io_ops, "parcMemory_AllocateAndClear(%zu) returned NULL", - sizeof(IoOperations)); - memcpy(io_ops, &_template, sizeof(IoOperations)); - io_ops->closure = hicnConnState; - - _setConnectionState(hicnConnState, true); - - if (logger_IsLoggable(hicnConnState->logger, LoggerFacility_IO, - PARCLogLevel_Info)) { - char *str = addressPair_ToString(hicnConnState->addressPair); - logger_Log(hicnConnState->logger, LoggerFacility_IO, PARCLogLevel_Info, - __func__, - "HicnConnection %p created for address %s (isLocal %d)", - (void *)hicnConnState, str, hicnConnState->isLocal); - free(str); - } - - messenger_Send( - forwarder_GetMessenger(forwarder), - missive_Create(MissiveType_ConnectionCreate, hicnConnState->id)); - messenger_Send(forwarder_GetMessenger(forwarder), - missive_Create(MissiveType_ConnectionUp, hicnConnState->id)); - } else { - // _saveSockaddr will already log an error, no need for extra log message - // here - logger_Release(&hicnConnState->logger); - parcMemory_Deallocate((void **)&hicnConnState); - } - - return io_ops; -} - -// ================================================================= -// I/O Operations implementation - -static void _destroy(IoOperations **opsPtr) { - parcAssertNotNull(opsPtr, "Parameter opsPtr must be non-null double pointer"); - parcAssertNotNull(*opsPtr, - "Parameter opsPtr must dereference to non-null pointer"); - - IoOperations *ops = *opsPtr; - parcAssertNotNull(ioOperations_GetClosure(ops), - "ops->context must not be null"); - - _HicnState *hicnConnState = (_HicnState *)ioOperations_GetClosure(ops); - addressPair_Release(&hicnConnState->addressPair); - parcMemory_Deallocate((void **)&(hicnConnState->peerAddress)); - parcMemory_Deallocate((void **)&(hicnConnState->localAddress)); - if (hicnConnState->probeDestAddress != NULL) - parcMemory_Deallocate((void **)&(hicnConnState->probeDestAddress)); - - messenger_Send( - forwarder_GetMessenger(hicnConnState->forwarder), - missive_Create(MissiveType_ConnectionDestroyed, hicnConnState->id)); - - if (logger_IsLoggable(hicnConnState->logger, LoggerFacility_IO, - PARCLogLevel_Info)) { - logger_Log(hicnConnState->logger, LoggerFacility_IO, PARCLogLevel_Info, - __func__, "HicnConnection %p destroyed", (void *)hicnConnState); - } - - // XXX - // do not close hicListenerSocket, the listener will close - // that when its done - // should I say something to libhicn? - - logger_Release(&hicnConnState->logger); - parcMemory_Deallocate((void **)&hicnConnState); - parcMemory_Deallocate((void **)&ops); - - *opsPtr = NULL; -} - -static bool _isUp(const IoOperations *ops) { - parcAssertNotNull(ops, "Parameter must be non-null"); - const _HicnState *hicnConnState = - (const _HicnState *)ioOperations_GetClosure(ops); - return hicnConnState->isUp; -} - -static bool _isLocal(const IoOperations *ops) { - parcAssertNotNull(ops, "Parameter must be non-null"); - const _HicnState *hicnConnState = - (const _HicnState *)ioOperations_GetClosure(ops); - return hicnConnState->isLocal; -} - -static const Address *_getRemoteAddress(const IoOperations *ops) { - parcAssertNotNull(ops, "Parameter must be non-null"); - const _HicnState *hicnConnState = - (const _HicnState *)ioOperations_GetClosure(ops); - return addressPair_GetRemote(hicnConnState->addressPair); -} - -static const AddressPair *_getAddressPair(const IoOperations *ops) { - parcAssertNotNull(ops, "Parameter must be non-null"); - const _HicnState *hicnConnState = - (const _HicnState *)ioOperations_GetClosure(ops); - return hicnConnState->addressPair; -} - -static unsigned _getConnectionId(const IoOperations *ops) { - parcAssertNotNull(ops, "Parameter must be non-null"); - const _HicnState *hicnConnState = - (const _HicnState *)ioOperations_GetClosure(ops); - return hicnConnState->id; -} - -/** - * @function hicnConnection_Send - * @abstract Non-destructive send of the message. - * @discussion - * sends a message to the peer. - * - * @param dummy is ignored. . - */ -static bool _send(IoOperations *ops, const Address *dummy, Message *message) { - parcAssertNotNull(ops, "Parameter ops must be non-null"); - parcAssertNotNull(message, "Parameter message must be non-null"); - _HicnState *hicnConnState = (_HicnState *)ioOperations_GetClosure(ops); - - // NAT for HICN - // XXX - if (message_GetType(message) == MessagePacketType_ContentObject) { - // this is a data packet. We need to put the remote address in the - // destination field - - if (messageHandler_GetIPPacketType(message_FixedHeader(message)) == - IPv6_TYPE) { - messageHandler_SetDestination_IPv6( - (uint8_t *)message_FixedHeader(message), - &((struct sockaddr_in6 *)hicnConnState->peerAddress)->sin6_addr); - } else { - messageHandler_SetDestination_IPv4( - (uint8_t *)message_FixedHeader(message), - &(((struct sockaddr_in *)hicnConnState->peerAddress) - ->sin_addr.s_addr)); - } - } else if (message_GetType(message) == MessagePacketType_Interest) { - // this si an interest packet. We need to put the local address in the - // source field - if (messageHandler_GetIPPacketType(message_FixedHeader(message)) == - IPv6_TYPE) { - messageHandler_SetSource_IPv6( - (uint8_t *)message_FixedHeader(message), - &((struct sockaddr_in6 *)hicnConnState->localAddress)->sin6_addr); - } else { - messageHandler_SetSource_IPv4( - (uint8_t *)message_FixedHeader(message), - &(((struct sockaddr_in *)hicnConnState->localAddress) - ->sin_addr.s_addr)); - } - - // only in this case we may need to set the probeDestAddress - if (hicnConnState->refreshProbeDestAddress) { - _refreshProbeDestAddress(hicnConnState, message_FixedHeader(message)); - } - - } else if (message_GetType(message) == MessagePacketType_WldrNotification) { - // here we don't need to do anything for now - } else { - // unkown packet - if (logger_IsLoggable(hicnConnState->logger, LoggerFacility_IO, - PARCLogLevel_Debug)) { - logger_Log(hicnConnState->logger, LoggerFacility_IO, PARCLogLevel_Debug, - __func__, "connid %u can't parse the message", - hicnConnState->id); - } - return false; - } - - ssize_t writeLength = - write(hicnConnState->hicnListenerSocket, message_FixedHeader(message), - message_Length(message)); - - if (writeLength < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - return false; - } else { - // this print is for debugging - printf("Incorrect write length %zd, expected %zd: (%d) %s\n", writeLength, - message_Length(message), errno, strerror(errno)); - return false; - } - } - - return true; -} - -static bool _sendCommandResponse(IoOperations *ops, struct iovec *message) { - //XXX this should be nerver called since we do not handle control messages - //with hicn connections, so nothing to do here! - return false; -} - -static list_connections_type _getConnectionType(const IoOperations *ops) { - return CONN_HICN; -} - -static Ticks _sendProbe(IoOperations *ops, unsigned probeType, - uint8_t *message) { - parcAssertNotNull(ops, "Parameter ops must be non-null"); - _HicnState *hicnConnState = (_HicnState *)ioOperations_GetClosure(ops); - - if ((hicnConnState->peerAddressLength == sizeof(struct sockaddr_in)) || - (hicnConnState->localAddressLength == sizeof(struct sockaddr_in))) - return false; - - if (hicnConnState->probeDestAddress == NULL && - probeType == PACKET_TYPE_PROBE_REPLY) { - uint8_t *pkt = parcMemory_AllocateAndClear( - messageHandler_GetICMPPacketSize(IPv6_TYPE)); - messageHandler_SetProbePacket( - pkt, probeType, - (struct in6_addr *)messageHandler_GetDestination(message), - (struct in6_addr *)messageHandler_GetSource(message)); - - ssize_t writeLength = write(hicnConnState->hicnListenerSocket, pkt, - messageHandler_GetICMPPacketSize(IPv6_TYPE)); - - parcMemory_Deallocate((void **)&pkt); - - if (writeLength < 0) { - return 0; - } - - } else if (hicnConnState->probeDestAddress != NULL && - probeType == PACKET_TYPE_PROBE_REQUEST) { - hicnConnState->refreshProbeDestAddress = true; - - uint8_t *pkt = parcMemory_AllocateAndClear( - messageHandler_GetICMPPacketSize(IPv6_TYPE)); - messageHandler_SetProbePacket( - pkt, probeType, - &((struct sockaddr_in6 *)hicnConnState->localAddress)->sin6_addr, - &((struct sockaddr_in6 *)hicnConnState->probeDestAddress)->sin6_addr); - - ssize_t writeLength = write(hicnConnState->hicnListenerSocket, pkt, - messageHandler_GetICMPPacketSize(IPv6_TYPE)); - - parcMemory_Deallocate((void **)&pkt); - - if (writeLength < 0) { - return 0; - } - - } else { - if (hicnConnState->probeDestAddress == NULL && - probeType == PACKET_TYPE_PROBE_REQUEST) { - // this happen for the first probe - hicnConnState->refreshProbeDestAddress = true; - } - // do nothing - return 0; - } - - return forwarder_GetTicks(hicnConnState->forwarder); -} - -// ================================================================= -// Internal API - -static bool _saveSockaddr(_HicnState *hicnConnState, const AddressPair *pair) { - bool success = false; - const Address *remoteAddress = addressPair_GetRemote(pair); - const Address *localAddress = addressPair_GetLocal(pair); - switch (addressGetType(remoteAddress)) { // local must be of the same type - - case ADDR_INET: { - size_t bytes = sizeof(struct sockaddr_in); - hicnConnState->peerAddress = parcMemory_Allocate(bytes); - parcAssertNotNull(hicnConnState->peerAddress, - "parcMemory_Allocate(%zu) returned NULL", bytes); - - addressGetInet(remoteAddress, - (struct sockaddr_in *)hicnConnState->peerAddress); - hicnConnState->peerAddressLength = (socklen_t)bytes; - - hicnConnState->localAddress = parcMemory_Allocate(bytes); - parcAssertNotNull(hicnConnState->localAddress, - "parcMemory_Allocate(%zu) returned NULL", bytes); - - addressGetInet(localAddress, - (struct sockaddr_in *)hicnConnState->localAddress); - hicnConnState->localAddressLength = (socklen_t)bytes; - - hicnConnState->probeDestAddress = NULL; - hicnConnState->probeDestAddressLength = (socklen_t)bytes; - hicnConnState->refreshProbeDestAddress = false; - - success = true; - break; - } - - case ADDR_INET6: { - size_t bytes = sizeof(struct sockaddr_in6); - hicnConnState->peerAddress = parcMemory_Allocate(bytes); - parcAssertNotNull(hicnConnState->peerAddress, - "parcMemory_Allocate(%zu) returned NULL", bytes); - - addressGetInet6(remoteAddress, - (struct sockaddr_in6 *)hicnConnState->peerAddress); - hicnConnState->peerAddressLength = (socklen_t)bytes; - - hicnConnState->localAddress = parcMemory_Allocate(bytes); - parcAssertNotNull(hicnConnState->localAddress, - "parcMemory_Allocate(%zu) returned NULL", bytes); - - addressGetInet6(localAddress, - (struct sockaddr_in6 *)hicnConnState->localAddress); - hicnConnState->localAddressLength = (socklen_t)bytes; - - hicnConnState->probeDestAddress = NULL; - hicnConnState->probeDestAddressLength = (socklen_t)bytes; - hicnConnState->refreshProbeDestAddress = false; - - success = true; - break; - } - - default: - if (logger_IsLoggable(hicnConnState->logger, LoggerFacility_IO, - PARCLogLevel_Error)) { - char *str = addressToString(remoteAddress); - logger_Log(hicnConnState->logger, LoggerFacility_IO, PARCLogLevel_Error, - __func__, "Remote address is not INET or INET6: %s", str); - parcMemory_Deallocate((void **)&str); - } - break; - } - return success; -} - -static void _refreshProbeDestAddress(_HicnState *hicnConnState, - const uint8_t *message) { - if ((hicnConnState->peerAddressLength == sizeof(struct sockaddr_in)) || - (hicnConnState->localAddressLength == sizeof(struct sockaddr_in))) - return; - - if (hicnConnState->probeDestAddress == NULL) { - hicnConnState->probeDestAddress = - parcMemory_AllocateAndClear(sizeof(struct sockaddr_in6)); - parcAssertNotNull(hicnConnState->probeDestAddress, - "parcMemory_Allocate(%zu) returned NULL", - sizeof(struct sockaddr_in6)); - } - - ((struct sockaddr_in6 *)hicnConnState->probeDestAddress)->sin6_family = - AF_INET6; - ((struct sockaddr_in6 *)hicnConnState->probeDestAddress)->sin6_port = - htons(1234); - ((struct sockaddr_in6 *)hicnConnState->probeDestAddress)->sin6_scope_id = 0; - ((struct sockaddr_in6 *)hicnConnState->probeDestAddress)->sin6_flowinfo = 0; - ((struct sockaddr_in6 *)hicnConnState->probeDestAddress)->sin6_addr = - *((struct in6_addr *)messageHandler_GetDestination(message)); - hicnConnState->refreshProbeDestAddress = false; -} - -static void _setConnectionState(_HicnState *hicnConnState, bool isUp) { - parcAssertNotNull(hicnConnState, "Parameter HICN must be non-null"); - - Messenger *messenger = forwarder_GetMessenger(hicnConnState->forwarder); - - bool oldStateIsUp = hicnConnState->isUp; - hicnConnState->isUp = isUp; - - if (oldStateIsUp && !isUp) { - // bring connection DOWN - Missive *missive = - missive_Create(MissiveType_ConnectionDown, hicnConnState->id); - messenger_Send(messenger, missive); - return; - } - - if (!oldStateIsUp && isUp) { - // bring connection UP - Missive *missive = - missive_Create(MissiveType_ConnectionUp, hicnConnState->id); - messenger_Send(messenger, missive); - return; - } -} |