From 79e0d4f89c4d532189aae06cc5dfbc14e3269703 Mon Sep 17 00:00:00 2001 From: Mauro Sardara Date: Mon, 11 Feb 2019 10:44:29 +0100 Subject: [HICN-50] Added udp application connector. Change-Id: I0c5afad4b404ec485f50b1342b81e70ef85a5163 Signed-off-by: Mauro Sardara Signed-off-by: michele papalini --- .../src/command_line/daemon/hicnLightDaemon_main.c | 5 +- hicn-light/src/config/configuration.c | 24 ++- hicn-light/src/config/configurationListeners.c | 21 +- hicn-light/src/config/configurationListeners.h | 3 + hicn-light/src/core/connection.c | 7 + hicn-light/src/core/connection.h | 6 + hicn-light/src/core/forwarder.c | 5 + hicn-light/src/core/forwarder.h | 6 + hicn-light/src/io/hicnConnection.c | 9 +- hicn-light/src/io/ioOperations.c | 6 + hicn-light/src/io/ioOperations.h | 36 +--- hicn-light/src/io/streamConnection.c | 38 +--- hicn-light/src/io/udpConnection.c | 94 +++------ hicn-light/src/io/udpListener.c | 216 +++++++++------------ hicn-light/src/utils/commands.h | 51 ++++- 15 files changed, 256 insertions(+), 271 deletions(-) (limited to 'hicn-light') diff --git a/hicn-light/src/command_line/daemon/hicnLightDaemon_main.c b/hicn-light/src/command_line/daemon/hicnLightDaemon_main.c index dac8ee89f..ce8c373ca 100644 --- a/hicn-light/src/command_line/daemon/hicnLightDaemon_main.c +++ b/hicn-light/src/command_line/daemon/hicnLightDaemon_main.c @@ -371,12 +371,9 @@ int main(int argc, const char *argv[]) { configuration_SetObjectStoreSize(configuration, capacity); } + forwarder_SetupLocalListeners(forwarder, port); if (configFileName) { - forwarder_SetupAllListeners(forwarder, port, NULL); forwarder_SetupFromConfigFile(forwarder, configFileName); - } else { - // NULL to not setup AF_UNIX - forwarder_SetupAllListeners(forwarder, port, NULL); } Dispatcher *dispatcher = forwarder_GetDispatcher(forwarder); diff --git a/hicn-light/src/config/configuration.c b/hicn-light/src/config/configuration.c index 1a41a9642..865dbca4d 100644 --- a/hicn-light/src/config/configuration.c +++ b/hicn-light/src/config/configuration.c @@ -115,7 +115,7 @@ struct iovec *configuration_ProcessRegisterHicnPrefix(Configuration *config, const char *symbolicOrConnid = control->symbolicOrConnid; - if (strcmp(symbolicOrConnid, "SELF_ROUTE") == 0) { + if (strcmp(symbolicOrConnid, "SELF") == 0) { success = forwarder_AddOrUpdateRoute(config->forwarder, control, ingressId); } else if (utils_IsNumber(symbolicOrConnid)) { // case for connid as input @@ -304,11 +304,14 @@ static void configuration_SendResponse(Configuration *config, struct iovec *msg, ConnectionTable *connectionTable = forwarder_GetConnectionTable(config->forwarder); const Connection *conn = connectionTable_FindById(connectionTable, egressId); - parcAssertNotNull(conn, - "Got null connection for control message we just received"); - IoOperations *ops = connection_GetIoOperations(conn); - streamState_SendCommandResponse(ops, msg); + if (conn == NULL) { + return; + } + + connection_SendCommandResponse(conn, msg); + //IoOperations *ops = connection_GetIoOperations(conn); + //streamState_SendCommandResponse(ops, msg); } struct iovec *configuration_ProcessCreateTunnel(Configuration *config, @@ -425,7 +428,8 @@ struct iovec *configuration_ProcessCreateTunnel(Configuration *config, */ struct iovec *configuration_ProcessRemoveTunnel(Configuration *config, - struct iovec *request) { + struct iovec *request, + unsigned ingressId) { header_control_message *header = request[0].iov_base; remove_connection_command *control = request[1].iov_base; @@ -434,7 +438,11 @@ struct iovec *configuration_ProcessRemoveTunnel(Configuration *config, const char *symbolicOrConnid = control->symbolicOrConnid; ConnectionTable *table = forwarder_GetConnectionTable(config->forwarder); - if (utils_IsNumber(symbolicOrConnid)) { + if (strcmp(symbolicOrConnid, "SELF") == 0) { + forwarder_RemoveConnectionIdFromRoutes(config->forwarder, ingressId); + connectionTable_RemoveById(table, ingressId); + success = true; + } else if (utils_IsNumber(symbolicOrConnid)) { // case for connid as input unsigned connid = (unsigned)strtold(symbolicOrConnid, NULL); @@ -997,7 +1005,7 @@ struct iovec *configuration_DispatchCommand(Configuration *config, break; case REMOVE_CONNECTION: - response = configuration_ProcessRemoveTunnel(config, control); + response = configuration_ProcessRemoveTunnel(config, control, ingressId); break; case REMOVE_ROUTE: diff --git a/hicn-light/src/config/configurationListeners.c b/hicn-light/src/config/configurationListeners.c index 01ab9a3e7..11276e2dd 100644 --- a/hicn-light/src/config/configurationListeners.c +++ b/hicn-light/src/config/configurationListeners.c @@ -217,7 +217,7 @@ static bool _setupTcpListenerOnInet(Forwarder *forwarder, ipv4_addr_t *addr4, struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; - addr.sin_port = *port; + addr.sin_port = htons(*port); addr.sin_addr.s_addr = *addr4; ListenerOps *ops = tcpListener_CreateInet(forwarder, addr); @@ -231,12 +231,13 @@ static bool _setupTcpListenerOnInet(Forwarder *forwarder, ipv4_addr_t *addr4, static bool _setupUdpListenerOnInet(Forwarder *forwarder, ipv4_addr_t *addr4, uint16_t *port) { + bool success = false; struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; - addr.sin_port = *port; + addr.sin_port = htons(*port); addr.sin_addr.s_addr = *addr4; ListenerOps *ops = udpListener_CreateInet(forwarder, addr); @@ -256,7 +257,7 @@ static bool _setupTcpListenerOnInet6Light(Forwarder *forwarder, struct sockaddr_in6 addr; memset(&addr, 0, sizeof(addr)); addr.sin6_family = AF_INET6; - addr.sin6_port = *port; + addr.sin6_port = htons(*port); addr.sin6_addr = *addr6; addr.sin6_scope_id = scopeId; @@ -276,7 +277,7 @@ static bool _setupUdpListenerOnInet6Light(Forwarder *forwarder, struct sockaddr_in6 addr; memset(&addr, 0, sizeof(addr)); addr.sin6_family = AF_INET6; - addr.sin6_port = *port; + addr.sin6_port = htons(*port); addr.sin6_addr = *addr6; addr.sin6_scope_id = 0; @@ -529,9 +530,13 @@ void configurationListeners_SetupAll(const Configuration *config, uint16_t port, } } - // if (localPath != NULL) { - // _setupLocalListener(forwarder, localPath); - //} - interfaceSetDestroy(&set); } + +void configurationListeners_SetutpLocalIPv4(const Configuration *config, + uint16_t port) { + Forwarder *forwarder = configuration_GetForwarder(config); + in_addr_t addr = inet_addr("127.0.0.1"); + _setupUdpListenerOnInet(forwarder, (ipv4_addr_t *) &(addr), &port); + _setupTcpListenerOnInet(forwarder, (ipv4_addr_t *) &(addr), &port); +} diff --git a/hicn-light/src/config/configurationListeners.h b/hicn-light/src/config/configurationListeners.h index 7332b0c64..c97617d81 100644 --- a/hicn-light/src/config/configurationListeners.h +++ b/hicn-light/src/config/configurationListeners.h @@ -47,6 +47,9 @@ void configurationListeners_SetupAll(const Configuration *config, uint16_t port, const char *localPath); +void configurationListeners_SetutpLocalIPv4(const Configuration *config, + uint16_t port); + bool configurationListeners_Remove(const Configuration *config); // light functions diff --git a/hicn-light/src/core/connection.c b/hicn-light/src/core/connection.c index 505bba081..525fe29c4 100644 --- a/hicn-light/src/core/connection.c +++ b/hicn-light/src/core/connection.c @@ -112,6 +112,13 @@ bool connection_Send(const Connection *conn, Message *message) { return false; } +bool connection_SendCommandResponse(const Connection *conn, struct iovec *msg){ + parcAssertNotNull(conn, "Parameter conn must be non-null"); + parcAssertNotNull(msg, "Parameter message must be non-null"); + + return ioOperations_SendCommandResponse(conn->ops, msg); +} + static void _sendProbe(Connection *conn, unsigned probeType, uint8_t *message) { parcAssertNotNull(conn, "Parameter conn must be non-null"); diff --git a/hicn-light/src/core/connection.h b/hicn-light/src/core/connection.h index b5c703527..56fa131b5 100644 --- a/hicn-light/src/core/connection.h +++ b/hicn-light/src/core/connection.h @@ -64,6 +64,12 @@ Connection *connection_Acquire(Connection *connection); */ bool connection_Send(const Connection *conn, Message *message); +/** + * @function connection_SendCommandResponse + * @abstract Sends a response (ack/nack) for a command + */ +bool connection_SendCommandResponse(const Connection *conn, struct iovec *msg); + /** * Return the `IoOperations` instance associated with the specified `Connection` * instance. diff --git a/hicn-light/src/core/forwarder.c b/hicn-light/src/core/forwarder.c index bceb206a3..2b00a35e5 100644 --- a/hicn-light/src/core/forwarder.c +++ b/hicn-light/src/core/forwarder.c @@ -277,6 +277,11 @@ void forwarder_SetupAllListeners(Forwarder *forwarder, uint16_t port, configurationListeners_SetupAll(forwarder->config, port, localPath); } +void forwarder_SetupLocalListeners(Forwarder *forwarder, uint16_t port) { + parcAssertNotNull(forwarder, "Parameter must be non-null"); + configurationListeners_SetutpLocalIPv4(forwarder->config, port); +} + void forwarder_SetupFromConfigFile(Forwarder *forwarder, const char *filename) { ConfigurationFile *configFile = configurationFile_Create(forwarder, filename); if (configFile) { diff --git a/hicn-light/src/core/forwarder.h b/hicn-light/src/core/forwarder.h index 6bc823294..de736a1f8 100644 --- a/hicn-light/src/core/forwarder.h +++ b/hicn-light/src/core/forwarder.h @@ -90,6 +90,12 @@ void forwarder_Destroy(Forwarder **ptr); */ void forwarder_SetupAllListeners(Forwarder *forwarder, uint16_t port, const char *localPath); +/** + * @function forwarder_SetupAllListeners + * @abstract Setup one tcp and one udp listener on address 127.0.0.1 and the + * given port + */ +void forwarder_SetupLocalListeners(Forwarder *forwarder, uint16_t port); /** * Configure hicn-light via a configuration file diff --git a/hicn-light/src/io/hicnConnection.c b/hicn-light/src/io/hicnConnection.c index 6def8ed43..991c0064e 100644 --- a/hicn-light/src/io/hicnConnection.c +++ b/hicn-light/src/io/hicnConnection.c @@ -75,6 +75,7 @@ typedef struct hicn_state { // 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); @@ -100,6 +101,7 @@ static const void *_streamConnection_Class(const IoOperations *ops) { static IoOperations _template = {.closure = NULL, .send = &_send, + .sendCommandResponse = &_sendCommandResponse, .getRemoteAddress = &_getRemoteAddress, .getAddressPair = &_getAddressPair, .getConnectionId = &_getConnectionId, @@ -253,7 +255,6 @@ static unsigned _getConnectionId(const IoOperations *ops) { * sends a message to the peer. * * @param dummy is ignored. . - * @return <#return#> */ static bool _send(IoOperations *ops, const Address *dummy, Message *message) { parcAssertNotNull(ops, "Parameter ops must be non-null"); @@ -328,6 +329,12 @@ static bool _send(IoOperations *ops, const Address *dummy, Message *message) { 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; } diff --git a/hicn-light/src/io/ioOperations.c b/hicn-light/src/io/ioOperations.c index bbc8cec91..b40b51d76 100644 --- a/hicn-light/src/io/ioOperations.c +++ b/hicn-light/src/io/ioOperations.c @@ -28,6 +28,12 @@ bool ioOperations_Send(IoOperations *ops, const Address *nexthop, return ops->send(ops, nexthop, message); } +bool ioOperations_SendCommandResponse(IoOperations *ops, + struct iovec *message) { + return ops->sendCommandResponse(ops, message); +} + + const Address *ioOperations_GetRemoteAddress(const IoOperations *ops) { return ops->getRemoteAddress(ops); } diff --git a/hicn-light/src/io/ioOperations.h b/hicn-light/src/io/ioOperations.h index dee66030d..48319c259 100644 --- a/hicn-light/src/io/ioOperations.h +++ b/hicn-light/src/io/ioOperations.h @@ -15,38 +15,6 @@ /** * Defines the interface all connections use to communicate with the forwarder. - * - * @code - * - * static IoOperations _template = { - * .closure = NULL, - * .send = &_etherConnection_Send, - * .getRemoteAddress = &_etherConnection_GetRemoteAddress, - * .getAddressPair = &_etherConnection_GetAddressPair, - * .getConnectionId = &_etherConnection_GetConnectionId, - * .isUp = &_etherConnection_IsUp, - * .isLocal = &_etherConnection_IsLocal, - * .destroy = &_etherConnection_DestroyOperations, - * .class = &_etherConnection_Class, - * .getConnectionType = &_etherConnection_getConnectionType - * }; - * - * IoOperations * - * etherConnection_Create(Forwarder *forwarder, GenericEther *ether, - * AddressPair *pair) - * { - * _EtherState *etherConnState = parcMemory_Allocate(sizeof(_EtherState)); - * // Fill in etherConnState with instance variables - * - * IoOperations *io_ops = parcMemory_Allocate(sizeof(IoOperations)); - * memcpy(io_ops, &_template, sizeof(IoOperations)); - * io_ops->closure = etherConnState; - * // Add to connection table, send missives about connection state - * - * return op_ops; - * } - * @endcode - * */ /** @@ -95,6 +63,7 @@ typedef struct io_ops IoOperations; struct io_ops { void *closure; bool (*send)(IoOperations *ops, const Address *nexthop, Message *message); + bool (*sendCommandResponse)(IoOperations *ops, struct iovec *message); const Address *(*getRemoteAddress)(const IoOperations *ops); const AddressPair *(*getAddressPair)(const IoOperations *ops); bool (*isUp)(const IoOperations *ops); @@ -201,6 +170,9 @@ void ioOperations_Release(IoOperations **opsPtr); bool ioOperations_Send(IoOperations *ops, const Address *nexthop, Message *message); +bool ioOperations_SendCommandResponse(IoOperations *ops, + struct iovec *message); + /** * A connection is made up of a local and a remote address. This function * returns the remote address. diff --git a/hicn-light/src/io/streamConnection.c b/hicn-light/src/io/streamConnection.c index 948b6c01b..78c19fb18 100644 --- a/hicn-light/src/io/streamConnection.c +++ b/hicn-light/src/io/streamConnection.c @@ -65,6 +65,8 @@ typedef struct stream_state { // Prototypes static bool _streamConnection_Send(IoOperations *ops, const Address *nexthop, Message *message); +static bool _streamConnection_SendCommandResponse(IoOperations *ops, + struct iovec *msg); static const Address *_streamConnection_GetRemoteAddress( const IoOperations *ops); static const AddressPair *_streamConnection_GetAddressPair( @@ -80,31 +82,6 @@ static list_connections_type _streamConnection_GetConnectionType( static Ticks _sendProbe(IoOperations *ops, unsigned probeType, uint8_t *message); -// REMINDER: when a new_command is added, the following array has to be updated -// with the sizeof(new_command). It allows to allocate the buffer for receiving -// the payload of the CONTROLLER REQUEST after the header has beed read. Each -// command identifier (typedef enum command_id) corresponds to a position in the -// following array. -static int payloadLengthDaemon[LAST_COMMAND_VALUE] = { - sizeof(add_listener_command), - sizeof(add_connection_command), - 0, // list connections: payload always 0 when get controller request - sizeof(add_route_command), - 0, // list routes: payload always 0 when get controller request - sizeof(remove_connection_command), - sizeof(remove_route_command), - sizeof(cache_store_command), - sizeof(cache_serve_command), - 0, // cache clear - sizeof(set_strategy_command), - sizeof(set_wldr_command), - sizeof(add_punting_command), - 0, // list listeners: payload always 0 when get controller request - sizeof(mapme_activator_command), - sizeof(mapme_activator_command), - sizeof(mapme_timing_command), - sizeof(mapme_timing_command)}; - /* * This assigns a unique pointer to the void * which we use * as a GUID for this class. @@ -121,6 +98,7 @@ static const void *_streamConnection_Class(const IoOperations *ops) { static IoOperations _template = { .closure = NULL, .send = &_streamConnection_Send, + .sendCommandResponse = &_streamConnection_SendCommandResponse, .getRemoteAddress = &_streamConnection_GetRemoteAddress, .getAddressPair = &_streamConnection_GetAddressPair, .getConnectionId = &_streamConnection_GetConnectionId, @@ -308,7 +286,7 @@ static unsigned _streamConnection_GetConnectionId(const IoOperations *ops) { return stream->id; } -bool streamState_SendCommandResponse(IoOperations *ops, +bool _streamConnection_SendCommandResponse(IoOperations *ops, struct iovec *response) { parcAssertNotNull(ops, "Parameter ops must be non-null"); parcAssertNotNull(response, "Parameter message must be non-null"); @@ -447,7 +425,7 @@ int _isACommand(PARCEventBuffer *input) { // read first byte of the header // first byte: must be a REQUEST_LIGHT - if (msg[0] != 100) { + if (msg[0] != REQUEST_LIGHT) { return LAST_COMMAND_VALUE; } @@ -468,7 +446,7 @@ PARCEventBuffer *_tryReadControlMessage(_StreamState *stream, if (stream->nextMessageLength == 0) { stream->nextMessageLength = sizeof(header_control_message) + - payloadLengthDaemon[command]; // consider the whole packet. + payloadLengthDaemon(command); // consider the whole packet. } if (bytesAvailable >= stream->nextMessageLength) { @@ -487,13 +465,13 @@ PARCEventBuffer *_tryReadControlMessage(_StreamState *stream, } (*request)[0].iov_base = control; // header (*request)[0].iov_len = sizeof(header_control_message); - if (payloadLengthDaemon[command] > 0) { + if (payloadLengthDaemon(command) > 0) { (*request)[1].iov_base = control + sizeof(header_control_message); // payload } else { (*request)[1].iov_base = NULL; } - (*request)[1].iov_len = payloadLengthDaemon[command]; + (*request)[1].iov_len = payloadLengthDaemon(command); // now reset message length for next packet stream->nextMessageLength = 0; diff --git a/hicn-light/src/io/udpConnection.c b/hicn-light/src/io/udpConnection.c index 6c2e35392..3faf2bfac 100644 --- a/hicn-light/src/io/udpConnection.c +++ b/hicn-light/src/io/udpConnection.c @@ -19,6 +19,7 @@ * NB The Send() function may overflow the output buffer * */ +#include #include #include @@ -58,6 +59,7 @@ typedef struct udp_state { // 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); @@ -82,6 +84,7 @@ static const void *_streamConnection_Class(const IoOperations *ops) { static IoOperations _template = {.closure = NULL, .send = &_send, + .sendCommandResponse = &_sendCommandResponse, .getRemoteAddress = &_getRemoteAddress, .getAddressPair = &_getAddressPair, .getConnectionId = &_getConnectionId, @@ -239,38 +242,6 @@ static bool _send(IoOperations *ops, const Address *dummy, Message *message) { // in this particular connection we don't need natting beacause we send the // packet to the next hop using upd connection -#if 0 - if((hicnConnState->peerAddressLength == sizeof(struct sockaddr_in)) || (hicnConnState->localAddressLength == sizeof(struct sockaddr_in))) - return false; - - if(message_GetType(message) = MessagePacketType_ContentObject){ - //this is a data packet. We need to put the remote address in the destination field - messageHandler_SetDestination_IPv6((uint8_t *) message_FixedHeader(message), - &((struct sockaddr_in6 *) hicnConnState->peerAddress)->sin6_addr); - - } else if (message_GetType(message) == MessagePacketType_Interest) { - //this si an interest packet. We need to put the local address in the source field - messageHandler_SetSource_IPv6((uint8_t *) message_FixedHeader(message), - &((struct sockaddr_in6 *) hicnConnState->localAddress)->sin6_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; - } -#endif - ssize_t writeLength = sendto(udpConnState->udpListenerSocket, message_FixedHeader(message), (int)message_Length(message), 0, udpConnState->peerAddress, @@ -290,44 +261,39 @@ static bool _send(IoOperations *ops, const Address *dummy, Message *message) { return true; } +static bool _sendCommandResponse(IoOperations *ops, struct iovec *message){ + parcAssertNotNull(ops, "Parameter ops must be non-null"); + parcAssertNotNull(message, "Parameter message must be non-null"); + _UdpState *udpConnState = (_UdpState *)ioOperations_GetClosure(ops); + + // 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, 2); + + 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; + } + + return true; +} + static list_connections_type _getConnectionType(const IoOperations *ops) { return CONN_UDP; } static Ticks _sendProbe(IoOperations *ops, unsigned probeType, uint8_t *message) { -#if 0 - parcAssertNotNull(ops, "Parameter ops must be non-null"); - _MetisUdpState *udpConnState = (_MetisUdpState *) metisIoOperations_GetClosure(ops); - - - uint8_t *pkt; - size_t pkt_size = 8; - pkt = (uint8_t *) malloc(sizeof(uint8_t) * pkt_size); - for (unsigned i = 0; i < pkt_size; i++) { - pkt[i] = 0; - } - pkt[0] = 1; //type - pkt[1] = probeType; //packet type - pkt[6] = 8; //header len (16bit, network order) - - ssize_t writeLen = sendto(udpConnState->udpListenerSocket, pkt, pkt_size, 0, udpConnState->peerAddress, udpConnState->peerAddressLength); - - if (writeLen < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - free(pkt); - return 0; - } else { - //this print is for debugging - printf("Incorrect write length %zd, expected %zd: (%d) %s\n", writeLen, pkt_size, errno, strerror(errno)); - free(pkt); - return 0; - } - } - - free(pkt); - return metisForwarder_GetTicks(udpConnState->metis); -#endif + //TODO return 0; } diff --git a/hicn-light/src/io/udpListener.c b/hicn-light/src/io/udpListener.c index 6c2947c66..4411bc7f6 100644 --- a/hicn-light/src/io/udpListener.c +++ b/hicn-light/src/io/udpListener.c @@ -282,54 +282,8 @@ static int _getSocket(const ListenerOps *ops) { return (int)udp->udp_socket; } -// void -// udpListener_SetPacketType(ListenerOps *ops, MessagePacketType type) -//{ -// return; -//} - // ===================================================================== -/** - * @function peekMesageLength - * @abstract Peek at the next packet to learn its length by reading the fixed - * header - * @discussion - * <#Discussion#> - * - * @param <#param1#> - * @return <#return#> - */ -static size_t _peekMessageLength(UdpListener *udp, int fd, - struct sockaddr *peerIpAddress, - socklen_t *peerIpAddressLengthPtr) { - // to be fast I try to use just ipv6, this needs to be validated for ipv4 - - size_t packetLength = 0; - - uint8_t *fixedHeader = (uint8_t *)malloc( - sizeof(uint8_t) * messageHandler_GetIPHeaderLength(IPv6)); - - // peek at the UDP packet and read in the fixed header. - // Also returns the socket information for the remote peer - - ssize_t res = recvfrom( - fd, fixedHeader, (int)messageHandler_GetIPHeaderLength(IPv6), MSG_PEEK, - (struct sockaddr *)peerIpAddress, peerIpAddressLengthPtr); - - if (res == messageHandler_GetIPHeaderLength(IPv6)) { - packetLength = messageHandler_GetTotalPacketLength(fixedHeader); - } else { - if (res < 0) { - printf("error while readin packet\n"); - } - } - - free(fixedHeader); - - return packetLength; -} - /** * @function _constructAddressPair * @abstract Creates the address pair that uniquely identifies the connection @@ -441,100 +395,108 @@ static void _handleWldrNotification(UdpListener *udp, unsigned connId, message_Release(&message); } -static Message *_readMessage(UdpListener *udp, int fd, size_t packetLength, - AddressPair *pair) { - uint8_t *msgBuffer = parcMemory_AllocateAndClear(packetLength); - - ssize_t readLength = read(fd, msgBuffer, (unsigned int)packetLength); +static Message *_readMessage(UdpListener *udp, int fd, + AddressPair *pair, uint8_t * packet, bool * processed) { Message *message = NULL; - if (readLength < 0) { - printf("read failed %d: (%d) %s\n", fd, errno, strerror(errno)); - return message; - } - unsigned connid = 0; bool foundConnection = _lookupConnectionId(udp, pair, &connid); - if (readLength == packetLength) { - // we need to check if it is a valid packet - if (messageHandler_IsTCP(msgBuffer)) { - MessagePacketType pktType; - - if (messageHandler_IsData(msgBuffer)) { - pktType = MessagePacketType_ContentObject; - if (!foundConnection) { - parcMemory_Deallocate((void **)&msgBuffer); - return message; - } - } else if (messageHandler_IsInterest(msgBuffer)) { - pktType = MessagePacketType_Interest; - if (!foundConnection) { - connid = _createNewConnection(udp, fd, pair); - } - } else { - printf("Got a packet that is not a data nor an interest, drop it!\n"); - parcMemory_Deallocate((void **)&msgBuffer); + if (messageHandler_IsTCP(packet)) { + *processed = true; + MessagePacketType pktType; + + if (messageHandler_IsData(packet)) { + pktType = MessagePacketType_ContentObject; + if (!foundConnection) { + parcMemory_Deallocate((void **)&packet); return message; } + } else if (messageHandler_IsInterest(packet)) { + pktType = MessagePacketType_Interest; + if (!foundConnection) { + connid = _createNewConnection(udp, fd, pair); + } + } else { + printf("Got a packet that is not a data nor an interest, drop it!\n"); + parcMemory_Deallocate((void **)&packet); + return message; + } - message = message_CreateFromByteArray( - connid, msgBuffer, pktType, forwarder_GetTicks(udp->forwarder), - forwarder_GetLogger(udp->forwarder)); + message = message_CreateFromByteArray( + connid, packet, pktType, forwarder_GetTicks(udp->forwarder), + forwarder_GetLogger(udp->forwarder)); - if (message == NULL) { - parcMemory_Deallocate((void **)&msgBuffer); - } - } else if (messageHandler_IsWldrNotification(msgBuffer)) { - _handleWldrNotification(udp, connid, msgBuffer); - } else if (messageHandler_IsLoadBalancerProbe(msgBuffer)) { - _handleProbeMessage(udp, msgBuffer); + if (message == NULL) { + parcMemory_Deallocate((void **)&packet); } + } else if (messageHandler_IsWldrNotification(packet)) { + *processed = true; + _handleWldrNotification(udp, connid, packet); + } else if (messageHandler_IsLoadBalancerProbe(packet)) { + *processed = true; + _handleProbeMessage(udp, packet); + } #ifdef WITH_MAPME - else if (mapMe_isMapMe(msgBuffer)) { - forwarder_ProcessMapMe(udp->forwarder, msgBuffer, connid); - } -#endif /* WITH_MAPME */ + else if (mapMe_isMapMe(packet)) { + *processed = true; + forwarder_ProcessMapMe(udp->forwarder, packet, connid); } +#endif /* WITH_MAPME */ return message; } -static void _receivePacket(UdpListener *udp, int fd, size_t packetLength, - struct sockaddr_storage *peerIpAddress, - socklen_t peerIpAddressLength) { - AddressPair *pair = _constructAddressPair( - udp, (struct sockaddr *)peerIpAddress, peerIpAddressLength); +static void _readCommand(UdpListener *udp, int fd, + AddressPair *pair, + uint8_t * command) { - Message *message = _readMessage(udp, fd, packetLength, pair); - addressPair_Release(&pair); + if (*command != REQUEST_LIGHT){ + printf("the message received is not a command, drop\n"); + return; + } - if (message) { - forwarder_Receive(udp->forwarder, message); - } else { + command_id id = *(command + 1); + + if ( id < 0 || id >= LAST_COMMAND_VALUE){ + printf("the message received is not a valid command, drop\n"); return; } + + unsigned connid = 0; + bool foundConnection = _lookupConnectionId(udp, pair, &connid); + if(!foundConnection){ + connid = _createNewConnection(udp, fd, pair); + } + + struct iovec *request; + if (!(request = (struct iovec *) parcMemory_AllocateAndClear( + sizeof(struct iovec) * 2))) { + return; + } + + request[0].iov_base = command; + request[0].iov_len = sizeof(header_control_message); + request[1].iov_base = command + sizeof(header_control_message); + request[1].iov_len = payloadLengthDaemon(id); + + forwarder_ReceiveCommand(udp->forwarder, id, request, connid); + parcMemory_Deallocate((void **) &command); + parcMemory_Deallocate((void **) &request); } -static void _readFrameToDiscard(UdpListener *udp, int fd) { - // we need to discard the frame. Read 1 byte. This will clear it off the - // stack. - uint8_t buffer; - ssize_t nread = read(fd, &buffer, 1); - if (nread == 1) { - if (logger_IsLoggable(udp->logger, LoggerFacility_IO, PARCLogLevel_Debug)) { - logger_Log(udp->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__, - "Discarded frame from fd %d", fd); - } - } else if (nread < 0) { - if (logger_IsLoggable(udp->logger, LoggerFacility_IO, PARCLogLevel_Error)) { - logger_Log(udp->logger, LoggerFacility_IO, PARCLogLevel_Error, __func__, - "Error trying to discard frame from fd %d: (%d) %s", fd, errno, - strerror(errno)); - } +static bool _receivePacket(UdpListener *udp, int fd, + AddressPair *pair, + uint8_t * packet) { + bool processed = false; + Message *message = _readMessage(udp, fd, pair, + packet, &processed); + if (message) { + forwarder_Receive(udp->forwarder, message); } + return processed; } static void _readcb(int fd, PARCEventType what, void *udpVoid) { @@ -553,14 +515,24 @@ static void _readcb(int fd, PARCEventType what, void *udpVoid) { struct sockaddr_storage peerIpAddress; socklen_t peerIpAddressLength = sizeof(peerIpAddress); - size_t packetLength = _peekMessageLength( - udp, fd, (struct sockaddr *)&peerIpAddress, &peerIpAddressLength); + //packet it deallocated by _receivePacket or _readCommand + uint8_t * packet = parcMemory_AllocateAndClear(1500); //max MTU + ssize_t readLength = recvfrom(fd, packet, 1500, 0, + (struct sockaddr *)&peerIpAddress, &peerIpAddressLength); - if (packetLength > 0) { - _receivePacket(udp, fd, packetLength, &peerIpAddress, - peerIpAddressLength); - } else { - _readFrameToDiscard(udp, fd); + if(readLength < 0) { + printf("unable to read the message\n"); + return; } + + AddressPair *pair = _constructAddressPair( + udp, (struct sockaddr *)&peerIpAddress, peerIpAddressLength); + + bool done = _receivePacket(udp, fd, pair, packet); + if(!done){ + _readCommand(udp, fd, pair, packet); + } + + addressPair_Release(&pair); } } diff --git a/hicn-light/src/utils/commands.h b/hicn-light/src/utils/commands.h index e276d8dd2..d4147cbdd 100644 --- a/hicn-light/src/utils/commands.h +++ b/hicn-light/src/utils/commands.h @@ -41,7 +41,7 @@ union commandAddr { }; typedef enum { - REQUEST_LIGHT = 100, + REQUEST_LIGHT = 0xc0, //this is a command RESPONSE_LIGHT, ACK_LIGHT, NACK_LIGHT, @@ -49,7 +49,7 @@ typedef enum { } message_type; typedef enum { - ADD_LISTENER, + ADD_LISTENER = 0, ADD_CONNECTION, LIST_CONNECTIONS, ADD_ROUTE, @@ -283,4 +283,51 @@ typedef struct { // SIZE=1 +//===== size of commands ====== +// REMINDER: when a new_command is added, the following switch has to be +// updated. +static inline int payloadLengthDaemon(command_id id) { + switch (id){ + case ADD_LISTENER: + return sizeof(add_listener_command); + case ADD_CONNECTION: + return sizeof(add_connection_command); + case LIST_CONNECTIONS: + return 0; // list connections: payload always 0 + case ADD_ROUTE: + return sizeof(add_route_command); + case LIST_ROUTES: + return 0; // list routes: payload always 0 + case REMOVE_CONNECTION: + return sizeof(remove_connection_command); + case REMOVE_ROUTE: + return sizeof(remove_route_command); + case CACHE_STORE: + return sizeof(cache_store_command); + case CACHE_SERVE: + return sizeof(cache_serve_command); + case CACHE_CLEAR: + return 0; // cache clear + case SET_STRATEGY: + return sizeof(set_strategy_command); + case SET_WLDR: + return sizeof(set_wldr_command); + case ADD_PUNTING: + return sizeof(add_punting_command); + case LIST_LISTENERS: + return 0; // list listeners: payload always 0 + case MAPME_ENABLE: + return sizeof(mapme_activator_command); + case MAPME_DISCOVERY: + return sizeof(mapme_activator_command); + case MAPME_TIMESCALE: + return sizeof(mapme_timing_command); + case MAPME_RETX: + return sizeof(mapme_timing_command); + case LAST_COMMAND_VALUE: + return 0; + default: + return 0; + } +} #endif -- cgit 1.2.3-korg