From 0a1c6b5565e20167d1f1f33a5a8b597f420b18b0 Mon Sep 17 00:00:00 2001 From: Jordan Augé Date: Fri, 26 Jul 2019 23:20:30 +0200 Subject: [HICN-252] Add per-application policy framework to hicn-light forwarder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I0531cd7a7de179581295ae34766c81cd9cf3e172 Signed-off-by: Jordan Augé Signed-off-by: Mauro Sardara Co-authored-by: Mauro Sardara --- hicn-light/src/hicn/io/hicnListener.c | 281 +++++++++++++++++++--------------- 1 file changed, 159 insertions(+), 122 deletions(-) (limited to 'hicn-light/src/hicn/io/hicnListener.c') diff --git a/hicn-light/src/hicn/io/hicnListener.c b/hicn-light/src/hicn/io/hicnListener.c index 40cdadcd6..e8cab9aca 100644 --- a/hicn-light/src/hicn/io/hicnListener.c +++ b/hicn-light/src/hicn/io/hicnListener.c @@ -29,12 +29,6 @@ #include #include #include -#ifdef WITH_MAPME -#include -#include -#include -#include -#endif /* WITH_MAPME */ #include #include #include @@ -82,13 +76,19 @@ static unsigned _getInterfaceIndex(const ListenerOps *ops); static const Address *_getListenAddress(const ListenerOps *ops); static EncapType _getEncapType(const ListenerOps *ops); static int _getSocket(const ListenerOps *ops); - -static ListenerOps _hicnTemplate = {.context = NULL, - .destroy = &_destroy, - .getInterfaceIndex = &_getInterfaceIndex, - .getListenAddress = &_getListenAddress, - .getEncapType = &_getEncapType, - .getSocket = &_getSocket}; +static unsigned _createNewConnection(ListenerOps *listener, int fd, const AddressPair *pair); +static const Connection * _lookupConnection(ListenerOps * listener, const AddressPair *pair); + +static ListenerOps _hicnTemplate = { + .context = NULL, + .destroy = &_destroy, + .getInterfaceIndex = &_getInterfaceIndex, + .getListenAddress = &_getListenAddress, + .getEncapType = &_getEncapType, + .getSocket = &_getSocket, + .createConnection = &_createNewConnection, + .lookupConnection = &_lookupConnection, +}; static void _hicnListener_readcb(int fd, PARCEventType what, void *hicnVoid); @@ -177,12 +177,6 @@ ListenerOps *hicnListener_CreateInet(Forwarder *forwarder, char *symbolic, parcAssertFalse(failure, "fcntl failed to set file descriptor flags (%d)", errno); - hicn->hicn_event = dispatcher_CreateNetworkEvent( - forwarder_GetDispatcher(forwarder), true, _hicnListener_readcb, - (void *)hicn, hicn->hicn_fd); - dispatcher_StartNetworkEvent(forwarder_GetDispatcher(forwarder), - hicn->hicn_event); - ListenerOps *ops = parcMemory_AllocateAndClear(sizeof(ListenerOps)); parcAssertNotNull(ops, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(ListenerOps)); @@ -190,6 +184,13 @@ ListenerOps *hicnListener_CreateInet(Forwarder *forwarder, char *symbolic, memcpy(ops, &_hicnTemplate, sizeof(ListenerOps)); ops->context = hicn; + hicn->hicn_event = dispatcher_CreateNetworkEvent( + forwarder_GetDispatcher(forwarder), true, _hicnListener_readcb, + (void *)ops, hicn->hicn_fd); + dispatcher_StartNetworkEvent(forwarder_GetDispatcher(forwarder), + hicn->hicn_event); + + if (logger_IsLoggable(hicn->logger, LoggerFacility_IO, PARCLogLevel_Debug)) { logger_Log(hicn->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__, "HicnListener %s created", symbolic); @@ -267,12 +268,6 @@ ListenerOps *hicnListener_CreateInet6(Forwarder *forwarder, char *symbolic, parcAssertFalse(failure, "fcntl failed to set file descriptor flags (%d)", errno); - hicn->hicn_event = dispatcher_CreateNetworkEvent( - forwarder_GetDispatcher(forwarder), true, _hicnListener_readcb, - (void *)hicn, hicn->hicn_fd); - dispatcher_StartNetworkEvent(forwarder_GetDispatcher(forwarder), - hicn->hicn_event); - ListenerOps *ops = parcMemory_AllocateAndClear(sizeof(ListenerOps)); parcAssertNotNull(ops, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(ListenerOps)); @@ -280,6 +275,12 @@ ListenerOps *hicnListener_CreateInet6(Forwarder *forwarder, char *symbolic, memcpy(ops, &_hicnTemplate, sizeof(ListenerOps)); ops->context = hicn; + hicn->hicn_event = dispatcher_CreateNetworkEvent( + forwarder_GetDispatcher(forwarder), true, _hicnListener_readcb, + (void *)ops, hicn->hicn_fd); + dispatcher_StartNetworkEvent(forwarder_GetDispatcher(forwarder), + hicn->hicn_event); + if (logger_IsLoggable(hicn->logger, LoggerFacility_IO, PARCLogLevel_Debug)) { logger_Log(hicn->logger, LoggerFacility_IO, PARCLogLevel_Debug, __func__, "HicnListener %s created", symbolic); @@ -405,7 +406,6 @@ static void _hicnListener_Destroy(HicnListener **listenerPtr) { HicnListener *hicn = *listenerPtr; - // close(hicn->hicn_fd); //XXX close the fd in the hicnlib (detroy listener?) dispatcher_DestroyNetworkEvent(forwarder_GetDispatcher(hicn->forwarder), &hicn->hicn_event); logger_Release(&hicn->logger); @@ -454,8 +454,6 @@ static void _readFrameToDiscard(HicnListener *hicn, int fd) { "Discarded frame from fd %d", fd); } } else if (nread < 0) { - printf("Error trying to discard frame from fd %d: (%d) %s", fd, errno, - strerror(errno)); if (logger_IsLoggable(hicn->logger, LoggerFacility_IO, PARCLogLevel_Error)) { logger_Log(hicn->logger, LoggerFacility_IO, PARCLogLevel_Error, __func__, @@ -465,8 +463,9 @@ static void _readFrameToDiscard(HicnListener *hicn, int fd) { } } -static unsigned _createNewConnection(HicnListener *hicn, int fd, +static unsigned _createNewConnection(ListenerOps * listener, int fd, const AddressPair *pair) { + HicnListener * hicn = (HicnListener *)listener->context; bool isLocal = false; // udpConnection_Create takes ownership of the pair @@ -479,8 +478,11 @@ static unsigned _createNewConnection(HicnListener *hicn, int fd, return connid; } -const Connection *_findConnectionFromPacket(HicnListener *hicn, - Address *packetSourceAddress) { +static const Connection * _lookupConnection(ListenerOps * listener, + const AddressPair *pair) { + HicnListener * hicn = (HicnListener*)listener->context; + const Address * packetSourceAddress = addressPair_GetLocal(pair); + const Connection *conn = NULL; if (hicn->connection_id != -1) { conn = connectionTable_FindById( @@ -500,7 +502,6 @@ const Connection *_findConnectionFromPacket(HicnListener *hicn, return conn; } -#if 0 static Address *_createAddressFromPacket(uint8_t *msgBuffer) { Address *packetAddr = NULL; if (messageHandler_GetIPPacketType(msgBuffer) == IPv6_TYPE) { @@ -522,25 +523,33 @@ static Address *_createAddressFromPacket(uint8_t *msgBuffer) { } return packetAddr; } -#endif -static void _handleProbeMessage(HicnListener *hicn, uint8_t *msgBuffer) { +static void _handleProbeMessage(ListenerOps * listener, uint8_t *msgBuffer) { + HicnListener * hicn = (HicnListener *)listener->context; + Address *packetAddr = _createAddressFromPacket(msgBuffer); + AddressPair * pair = addressPair_Create(packetAddr, /* dummy */ hicn->localAddress); - if (packetAddr != NULL) { - const Connection *conn = _findConnectionFromPacket(hicn, packetAddr); - if (conn != NULL) { - // we drop all the probes for a connection that does not exists - connection_HandleProbe((Connection *)conn, msgBuffer, - forwarder_GetTicks(hicn->forwarder)); - } - } + if (!packetAddr) + goto DROP; + + // we drop all the probes for a connection that does not exists + const Connection *conn = _lookupConnection(listener, pair); + if (!conn) + goto DROP; + + connection_HandleProbe((Connection *)conn, msgBuffer, + forwarder_GetTicks(hicn->forwarder)); +DROP: + addressPair_Release(&pair); addressDestroy(&packetAddr); parcMemory_Deallocate((void **)&msgBuffer); } -static void _handleWldrNotification(HicnListener *hicn, uint8_t *msgBuffer) { +static void _handleWldrNotification(ListenerOps *listener, uint8_t *msgBuffer) { + HicnListener * hicn = (HicnListener *)listener->context; + Address *packetAddr = _createAddressFromPacket(msgBuffer); if (packetAddr == NULL) { @@ -548,14 +557,18 @@ static void _handleWldrNotification(HicnListener *hicn, uint8_t *msgBuffer) { return; } - const Connection *conn = _findConnectionFromPacket(hicn, packetAddr); + AddressPair * pair = addressPair_Create(packetAddr, /* dummy */ hicn->localAddress); + + const Connection *conn = _lookupConnection(listener, pair); + + addressPair_Release(&pair); + addressDestroy(&packetAddr); + if (conn == NULL) { - addressDestroy(&packetAddr); + parcMemory_Deallocate((void **)&msgBuffer); return; } - addressDestroy(&packetAddr); - Message *message = message_CreateFromByteArray( connection_GetConnectionId(conn), msgBuffer, MessagePacketType_WldrNotification, forwarder_GetTicks(hicn->forwarder), @@ -566,75 +579,87 @@ static void _handleWldrNotification(HicnListener *hicn, uint8_t *msgBuffer) { message_Release(&message); } -#ifdef WITH_MAPME -static void _handleMapMe(HicnListener *hicn, int fd, uint8_t *msgBuffer) { - Address *packetAddr = _createAddressFromPacket(msgBuffer); - - if (packetAddr == NULL) { - parcMemory_Deallocate((void **)&msgBuffer); - return; - } - - const Connection *conn = _findConnectionFromPacket(hicn, packetAddr); - unsigned conn_id; - if (conn == NULL) { - /* Unlike the interest path, we don't create virtual connections bound - * on the listener, whose only interest is to send data, but full - * tunnels to be able to route interests - * - * packetAddr is the remote address, we need to ask the lib for our - * local address - * hicn->localAddress is None as the interest is received by the main - * listener. - */ - printf("MapMe, connection did not exist, creating\n"); - - /* Populate remote_address through packetAddr */ - struct sockaddr_in6 sockaddr; // XXX IPv6 only - addressGetInet6(packetAddr, &sockaddr); - ip_address_t remote_address = {.family = AF_INET6, - .prefix_len = IPV6_ADDR_LEN_BITS}; - memcpy(&remote_address.buffer, &sockaddr.sin6_addr, - ip_address_len(&remote_address)); - - /* Get local address through libhicn */ - ip_address_t local_address; - int rc = hicn_get_local_address(&remote_address, &local_address); - if (rc < 0) { - printf("Error getting local address. Discarded mapme packet.\n"); - return; - } +static const +AddressPair * +_createRecvAddressPairFromPacket(const uint8_t *msgBuffer) { + Address *packetSrcAddr = NULL; /* This one is in the packet */ + Address *localAddr = NULL; /* This one is to be determined */ + if (messageHandler_GetIPPacketType(msgBuffer) == IPv6_TYPE) { struct sockaddr_in6 addr_in6; addr_in6.sin6_family = AF_INET6; addr_in6.sin6_port = htons(1234); addr_in6.sin6_flowinfo = 0; addr_in6.sin6_scope_id = 0; - memcpy(&addr_in6.sin6_addr, (struct in6_addr *)&(local_address.buffer), 16); + memcpy(&addr_in6.sin6_addr, + (struct in6_addr *)messageHandler_GetSource(msgBuffer), 16); + packetSrcAddr = addressCreateFromInet6(&addr_in6); + + /* We now determine the local address used to reach the packet src address */ + int sock = socket (AF_INET6, SOCK_DGRAM, 0); + if (sock < 0) + goto ERR; + + struct sockaddr_in6 remote, local; + memset(&remote, 0, sizeof(remote)); + remote.sin6_family = AF_INET6; + remote.sin6_addr = addr_in6.sin6_addr; + remote.sin6_port = htons(1234); + + socklen_t locallen = sizeof(local); + if (connect(sock, (const struct sockaddr*)&remote, sizeof(remote)) == -1) + goto ERR; + if (getsockname(sock, (struct sockaddr*) &local, &locallen) == -1) + goto ERR; - Address *localAddr = addressCreateFromInet6(&addr_in6); - IoOperations *ops = - hicnTunnel_Create(hicn->forwarder, localAddr, packetAddr); + local.sin6_port = htons(1234); + localAddr = addressCreateFromInet6(&local); - if (!ops) { - printf("Error creating tunnel. Discarded mapme packet.\n"); - return; + close(sock); + + } else if (messageHandler_GetIPPacketType(msgBuffer) == IPv4_TYPE) { + struct sockaddr_in addr_in; + addr_in.sin_family = AF_INET; + addr_in.sin_port = htons(1234); + memcpy(&addr_in.sin_addr, + (struct in_addr *)messageHandler_GetSource(msgBuffer), 4); + packetSrcAddr = addressCreateFromInet(&addr_in); + + /* We now determine the local address used to reach the packet src address */ + + int sock = socket (AF_INET, SOCK_DGRAM, 0); + if (sock < 0) { + perror("Socket error"); + goto ERR; } - conn = connection_Create(ops); + struct sockaddr_in remote, local; + memset(&remote, 0, sizeof(remote)); + remote.sin_family = AF_INET; + remote.sin_addr = addr_in.sin_addr; + remote.sin_port = htons(1234); - connectionTable_Add(forwarder_GetConnectionTable(hicn->forwarder), - (Connection *)conn); - } - conn_id = connection_GetConnectionId(conn); + socklen_t locallen = sizeof(local); + if (connect(sock, (const struct sockaddr*)&remote, sizeof(remote)) == -1) + goto ERR; + if (getsockname(sock, (struct sockaddr*) &local, &locallen) == -1) + goto ERR; - addressDestroy(&packetAddr); + local.sin_port = htons(1234); + localAddr = addressCreateFromInet(&local); + + close(sock); + } + /* As this is a receive pair, we swap src and dst */ + return addressPair_Create(localAddr, packetSrcAddr); - forwarder_ProcessMapMe(hicn->forwarder, msgBuffer, conn_id); +ERR: + perror("Socket error"); + return NULL; } -#endif /* WITH_MAPME */ -static Message *_readMessage(HicnListener *hicn, int fd, uint8_t *msgBuffer) { +static Message *_readMessage(ListenerOps * listener, int fd, uint8_t *msgBuffer) { + HicnListener * hicn = (HicnListener*)listener->context; Message *message = NULL; ssize_t readLength = read(fd, msgBuffer, MTU_SIZE); @@ -667,11 +692,13 @@ static Message *_readMessage(HicnListener *hicn, int fd, uint8_t *msgBuffer) { // run time) uses as a local address 0::0, so the main tun pktType = MessagePacketType_Interest; Address *packetAddr = _createAddressFromPacket(msgBuffer); - const Connection *conn = _findConnectionFromPacket(hicn, packetAddr); + AddressPair *pair_find = addressPair_Create(packetAddr, /* dummy */ hicn->localAddress); + const Connection *conn = _lookupConnection(listener, pair_find); + addressPair_Release(&pair_find); if (conn == NULL) { AddressPair *pair = addressPair_Create(hicn->localAddress, packetAddr); - connid = _createNewConnection(hicn, fd, pair); + connid = _createNewConnection(listener, fd, pair); addressPair_Release(&pair); } else { connid = connection_GetConnectionId(conn); @@ -690,42 +717,52 @@ static Message *_readMessage(HicnListener *hicn, int fd, uint8_t *msgBuffer) { parcMemory_Deallocate((void **)&msgBuffer); } } else if (messageHandler_IsWldrNotification(msgBuffer)) { - _handleWldrNotification(hicn, msgBuffer); + _handleWldrNotification(listener, msgBuffer); } else if (messageHandler_IsLoadBalancerProbe(msgBuffer)) { - _handleProbeMessage(hicn, msgBuffer); -#ifdef WITH_MAPME - } else if (mapMe_isMapMe(msgBuffer)) { - /* This function triggers the handling of the MAP-Me message, and we - * will return NULL so as to terminate the processing of this - * msgBuffer. */ - _handleMapMe(hicn, fd, msgBuffer); -#endif /* WITH_MAPME */ - } + _handleProbeMessage(listener, msgBuffer); + } else { + const AddressPair * pair = _createRecvAddressPairFromPacket(msgBuffer); + if (!pair) + goto ERR; + + /* Find connection and eventually create it */ + const Connection * conn = connectionTable_FindByAddressPair( + forwarder_GetConnectionTable(hicn->forwarder), pair); + unsigned conn_id; + if (conn == NULL) { + conn_id = listener->createConnection(listener, fd, pair); + } else { + conn_id = connection_GetConnectionId(conn); + } - if (messageHandler_handleHooks(hicn->forwarder, hicn->connection_id, - hicn->localAddress, msgBuffer)) - goto END; + messageHandler_handleHooks(hicn->forwarder, msgBuffer, conn_id); + +ERR: + parcMemory_Deallocate((void **)&msgBuffer); + + } -END: return message; } -static void _receivePacket(HicnListener *hicn, int fd) { +static void _receivePacket(ListenerOps * listener, int fd) { + HicnListener * hicn = (HicnListener*)listener->context; Message *msg = NULL; uint8_t *msgBuffer = parcMemory_AllocateAndClear(MTU_SIZE); - msg = _readMessage(hicn, fd, msgBuffer); + msg = _readMessage(listener, fd, msgBuffer); if (msg) { forwarder_Receive(hicn->forwarder, msg); } } -static void _hicnListener_readcb(int fd, PARCEventType what, void *hicnVoid) { - HicnListener *hicn = (HicnListener *)hicnVoid; +static void _hicnListener_readcb(int fd, PARCEventType what, void *listener_void) { + ListenerOps * listener = (ListenerOps *)listener_void; + HicnListener *hicn = (HicnListener *)listener->context; if (hicn->inetFamily == IPv4 || hicn->inetFamily == IPv6) { if (what & PARCEventType_Read) { - _receivePacket(hicn, fd); + _receivePacket(listener, fd); } } else { _readFrameToDiscard(hicn, fd); -- cgit 1.2.3-korg