From 15ad172a847fa667c57a4594ef4158405db9a984 Mon Sep 17 00:00:00 2001 From: Angelo Mantellini Date: Tue, 31 Mar 2020 17:50:43 +0200 Subject: [HICN-554] hicn-light refactoring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I36f2d393741d4502ce14d3791158e43e3e9cd4cf Signed-off-by: Jordan Augé --- hicn-light/src/hicn/io/udpConnection.c | 495 --------------------------------- 1 file changed, 495 deletions(-) delete mode 100644 hicn-light/src/hicn/io/udpConnection.c (limited to 'hicn-light/src/hicn/io/udpConnection.c') diff --git a/hicn-light/src/hicn/io/udpConnection.c b/hicn-light/src/hicn/io/udpConnection.c deleted file mode 100644 index cd3ccc84a..000000000 --- a/hicn-light/src/hicn/io/udpConnection.c +++ /dev/null @@ -1,495 +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 UDP connection - * - * NB The Send() function may overflow the output buffer - * - */ - -#ifndef _WIN32 -#include -#endif -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -typedef struct udp_state { - Forwarder *forwarder; - char * interfaceName; - Logger *logger; - - // the udp listener socket we receive packets on - int udpListenerSocket; - - AddressPair *addressPair; - - // We need to access this all the time, so grab it out - // of the addressPair; - struct sockaddr *peerAddress; - socklen_t peerAddressLength; - - bool isLocal; - bool isUp; - unsigned id; - - unsigned delay; - - /* This information would better be stored in the connection data structure - * but it is currently not reachable from within the implementation. */ - connection_state_t state; - connection_state_t admin_state; -#ifdef WITH_POLICY - uint32_t priority; -#endif /* WITH_POLICY */ -} _UdpState; - -// Prototypes -static bool _send(IoOperations *ops, const Address *nexthop, Message *message); -static bool _sendIOVBuffer(IoOperations *ops, struct iovec *message, - size_t size); -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 void _sendProbe(IoOperations *ops, uint8_t *message); -static connection_state_t _getState(const IoOperations *ops); -static void _setState(IoOperations *ops, connection_state_t state); -static connection_state_t _getAdminState(const IoOperations *ops); -static void _setAdminState(IoOperations *ops, connection_state_t admin_state); -#ifdef WITH_POLICY -static uint32_t _getPriority(const IoOperations *ops); -static void _setPriority(IoOperations *ops, uint32_t priority); -#endif /* WITH_POLICY */ -static const char * _getInterfaceName(const IoOperations *ops); - -/* - * 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, - .sendIOVBuffer = &_sendIOVBuffer, - .getRemoteAddress = &_getRemoteAddress, - .getAddressPair = &_getAddressPair, - .getConnectionId = &_getConnectionId, - .isUp = &_isUp, - .isLocal = &_isLocal, - .destroy = &_destroy, - .class = &_streamConnection_Class, - .getConnectionType = &_getConnectionType, - .sendProbe = &_sendProbe, - .getState = &_getState, - .setState = &_setState, - .getAdminState = &_getAdminState, - .setAdminState = &_setAdminState, -#ifdef WITH_POLICY - .getPriority = &_getPriority, - .setPriority = &_setPriority, -#endif /* WITH_POLICY */ - .getInterfaceName = &_getInterfaceName, -}; - -// ================================================================= - -static void _setConnectionState(_UdpState *Udp, bool isUp); -static bool _saveSockaddr(_UdpState *udpConnState, const AddressPair *pair); - -IoOperations *udpConnection_Create(Forwarder *forwarder, const char * interfaceName, int fd, - const AddressPair *pair, bool isLocal) { - IoOperations *io_ops = NULL; - - _UdpState *udpConnState = parcMemory_AllocateAndClear(sizeof(_UdpState)); - parcAssertNotNull(udpConnState, - "parcMemory_AllocateAndClear(%zu) returned NULL", - sizeof(_UdpState)); - - udpConnState->forwarder = forwarder; - udpConnState->interfaceName = strdup(interfaceName); - udpConnState->logger = logger_Acquire(forwarder_GetLogger(forwarder)); - - bool saved = _saveSockaddr(udpConnState, pair); - if (saved) { - udpConnState->udpListenerSocket = fd; - udpConnState->id = forwarder_GetNextConnectionId(forwarder); - udpConnState->addressPair = addressPair_Acquire(pair); - udpConnState->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 = udpConnState; - - _setConnectionState(udpConnState, true); - -#ifdef WITH_POLICY - udpConnState->priority = 0; -#endif /* WITH_POLICY */ - - if (logger_IsLoggable(udpConnState->logger, LoggerFacility_IO, - PARCLogLevel_Info)) { - char *str = addressPair_ToString(udpConnState->addressPair); - logger_Log(udpConnState->logger, LoggerFacility_IO, PARCLogLevel_Info, - __func__, - "UdpConnection %p created for address %s (isLocal %d)", - (void *)udpConnState, str, udpConnState->isLocal); - free(str); - } - - messenger_Send( - forwarder_GetMessenger(forwarder), - missive_Create(MissiveType_ConnectionCreate, udpConnState->id)); - messenger_Send(forwarder_GetMessenger(forwarder), - missive_Create(MissiveType_ConnectionUp, udpConnState->id)); - } else { - // _saveSockaddr will already log an error, no need for extra log message - // here - logger_Release(&udpConnState->logger); - - free(udpConnState->interfaceName); - parcMemory_Deallocate((void **)&udpConnState); - } - - 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"); - - _UdpState *udpConnState = (_UdpState *)ioOperations_GetClosure(ops); - addressPair_Release(&udpConnState->addressPair); - parcMemory_Deallocate((void **)&(udpConnState->peerAddress)); - - messenger_Send( - forwarder_GetMessenger(udpConnState->forwarder), - missive_Create(MissiveType_ConnectionDestroyed, udpConnState->id)); - - if (logger_IsLoggable(udpConnState->logger, LoggerFacility_IO, - PARCLogLevel_Info)) { - logger_Log(udpConnState->logger, LoggerFacility_IO, PARCLogLevel_Info, - __func__, "UdpConnection %p destroyed", (void *)udpConnState); - } - - // do not close udp->udpListenerSocket, the listener will close - // that when its done - - logger_Release(&udpConnState->logger); - free(udpConnState->interfaceName); - parcMemory_Deallocate((void **)&udpConnState); - parcMemory_Deallocate((void **)&ops); - - *opsPtr = NULL; -} - -static bool _isUp(const IoOperations *ops) { - parcAssertNotNull(ops, "Parameter must be non-null"); - const _UdpState *udpConnState = - (const _UdpState *)ioOperations_GetClosure(ops); - return udpConnState->isUp; -} - -static bool _isLocal(const IoOperations *ops) { - parcAssertNotNull(ops, "Parameter must be non-null"); - const _UdpState *udpConnState = - (const _UdpState *)ioOperations_GetClosure(ops); - return udpConnState->isLocal; -} - -static const Address *_getRemoteAddress(const IoOperations *ops) { - parcAssertNotNull(ops, "Parameter must be non-null"); - const _UdpState *udpConnState = - (const _UdpState *)ioOperations_GetClosure(ops); - return addressPair_GetRemote(udpConnState->addressPair); -} - -static const AddressPair *_getAddressPair(const IoOperations *ops) { - parcAssertNotNull(ops, "Parameter must be non-null"); - const _UdpState *udpConnState = - (const _UdpState *)ioOperations_GetClosure(ops); - return udpConnState->addressPair; -} - -static unsigned _getConnectionId(const IoOperations *ops) { - parcAssertNotNull(ops, "Parameter must be non-null"); - const _UdpState *udpConnState = - (const _UdpState *)ioOperations_GetClosure(ops); - return udpConnState->id; -} - -/** - * @function metisUdpConnection_Send - * @abstract Non-destructive send of the message. - * @discussion - * sends a message to the peer. - * - * @param dummy is ignored. A udp connection has only one peer. - * @return <#return#> - */ -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"); - _UdpState *udpConnState = (_UdpState *)ioOperations_GetClosure(ops); - - // NAT for HICN - // in this particular connection we don't need natting beacause we send the - // packet to the next hop using upd connection - - ssize_t writeLength = - sendto(udpConnState->udpListenerSocket, message_FixedHeader(message), - (int)message_Length(message), 0, udpConnState->peerAddress, - udpConnState->peerAddressLength); - - 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 _sendIOVBuffer(IoOperations *ops, struct iovec *message, - size_t size) { - parcAssertNotNull(ops, "Parameter ops must be non-null"); - parcAssertNotNull(message, "Parameter message must be non-null"); - _UdpState *udpConnState = (_UdpState *)ioOperations_GetClosure(ops); - -#ifndef _WIN32 - // Perform connect before to establish association between this peer and - // the remote peer. This is required to use writev. - // Connection association can be changed at any time. - connect(udpConnState->udpListenerSocket, - udpConnState->peerAddress, - udpConnState->peerAddressLength); - - ssize_t writeLength = writev(udpConnState->udpListenerSocket, message, (int)size); - - struct sockaddr any_address = {0}; - any_address.sa_family = AF_UNSPEC; - connect(udpConnState->udpListenerSocket, - &any_address, (socklen_t)sizeof(any_address)); - - if (writeLength < 0) { - return false; - } -#else - - WSABUF *dataBuf = (WSABUF *) malloc(size * sizeof (dataBuf)); - DWORD BytesSent = 0; - - for (int i = 0; i < size; i++) { - dataBuf[i].buf = message[i].iov_base; - dataBuf[i].len = (ULONG)message[i].iov_len; - } - - int rc = WSASendTo(udpConnState->udpListenerSocket, dataBuf, size, - &BytesSent, 0, (SOCKADDR *)udpConnState->peerAddress, - udpConnState->peerAddressLength, NULL, NULL); - free(dataBuf); - if (rc == SOCKET_ERROR) { - return false; - } -#endif - return true; -} - -static list_connections_type _getConnectionType(const IoOperations *ops) { - return CONN_UDP; -} - -static void _sendProbe(IoOperations *ops, uint8_t *message) { - parcAssertNotNull(ops, "Parameter ops must be non-null"); - parcAssertNotNull(message, "Parameter message must be non-null"); - _UdpState *udpConnState = (_UdpState *)ioOperations_GetClosure(ops); - - if(udpConnState->isLocal) - return; - - ssize_t writeLength = - sendto(udpConnState->udpListenerSocket, message, - messageHandler_GetTotalPacketLength(message), 0, udpConnState->peerAddress, - udpConnState->peerAddressLength); - - if (writeLength < 0) { - return; - } -} - -// ================================================================= -// Internal API - -static bool _saveSockaddr(_UdpState *udpConnState, const AddressPair *pair) { - bool success = false; - const Address *remoteAddress = addressPair_GetRemote(pair); - - switch (addressGetType(remoteAddress)) { - case ADDR_INET: { - size_t bytes = sizeof(struct sockaddr_in); - udpConnState->peerAddress = parcMemory_Allocate(bytes); - parcAssertNotNull(udpConnState->peerAddress, - "parcMemory_Allocate(%zu) returned NULL", bytes); - - addressGetInet(remoteAddress, - (struct sockaddr_in *)udpConnState->peerAddress); - udpConnState->peerAddressLength = (socklen_t)bytes; - - success = true; - break; - } - - case ADDR_INET6: { - size_t bytes = sizeof(struct sockaddr_in6); - udpConnState->peerAddress = parcMemory_Allocate(bytes); - parcAssertNotNull(udpConnState->peerAddress, - "parcMemory_Allocate(%zu) returned NULL", bytes); - - addressGetInet6(remoteAddress, - (struct sockaddr_in6 *)udpConnState->peerAddress); - udpConnState->peerAddressLength = (socklen_t)bytes; - - success = true; - break; - } - - default: - if (logger_IsLoggable(udpConnState->logger, LoggerFacility_IO, - PARCLogLevel_Error)) { - char *str = addressToString(remoteAddress); - logger_Log(udpConnState->logger, LoggerFacility_IO, PARCLogLevel_Error, - __func__, "Remote address is not INET or INET6: %s", str); - parcMemory_Deallocate((void **)&str); - } - break; - } - return success; -} - -static void _setConnectionState(_UdpState *udpConnState, bool isUp) { - parcAssertNotNull(udpConnState, "Parameter Udp must be non-null"); - - Messenger *messenger = forwarder_GetMessenger(udpConnState->forwarder); - - bool oldStateIsUp = udpConnState->isUp; - udpConnState->isUp = isUp; - - if (oldStateIsUp && !isUp) { - // bring connection DOWN - Missive *missive = - missive_Create(MissiveType_ConnectionDown, udpConnState->id); - messenger_Send(messenger, missive); - return; - } - - if (!oldStateIsUp && isUp) { - // bring connection UP - Missive *missive = - missive_Create(MissiveType_ConnectionUp, udpConnState->id); - messenger_Send(messenger, missive); - return; - } -} - -static connection_state_t _getState(const IoOperations *ops) { - parcAssertNotNull(ops, "Parameter must be non-null"); - const _UdpState *udpConnState = - (const _UdpState *)ioOperations_GetClosure(ops); - return udpConnState->state; -} - -static void _setState(IoOperations *ops, connection_state_t state) { - parcAssertNotNull(ops, "Parameter must be non-null"); - _UdpState *udpConnState = - (_UdpState *)ioOperations_GetClosure(ops); - udpConnState->state = state; -} - -static connection_state_t _getAdminState(const IoOperations *ops) { - parcAssertNotNull(ops, "Parameter must be non-null"); - const _UdpState *udpConnState = - (const _UdpState *)ioOperations_GetClosure(ops); - return udpConnState->admin_state; -} - -static void _setAdminState(IoOperations *ops, connection_state_t admin_state) { - parcAssertNotNull(ops, "Parameter must be non-null"); - _UdpState *udpConnState = - (_UdpState *)ioOperations_GetClosure(ops); - udpConnState->admin_state = admin_state; -} - -#ifdef WITH_POLICY -static uint32_t _getPriority(const IoOperations *ops) { - parcAssertNotNull(ops, "Parameter must be non-null"); - const _UdpState *udpConnState = - (const _UdpState *)ioOperations_GetClosure(ops); - return udpConnState->priority; -} - -static void _setPriority(IoOperations *ops, uint32_t priority) { - parcAssertNotNull(ops, "Parameter must be non-null"); - _UdpState *udpConnState = - (_UdpState *)ioOperations_GetClosure(ops); - udpConnState->priority = priority; -} -#endif /* WITH_POLICY */ - -static const char * _getInterfaceName(const IoOperations *ops) -{ - parcAssertNotNull(ops, "Parameter must be non-null"); - _UdpState *udpConnState = - (_UdpState *)ioOperations_GetClosure(ops); - return udpConnState->interfaceName; -} -- cgit 1.2.3-korg