Commit 8094890c authored by kfox's avatar kfox

Documentation and cleanup (created BEFS header file)

parent 91c8d99e
......@@ -30,10 +30,10 @@
*/
/*
* Provide support for loadable ethernet fragmentation modules. The fragmenter library is named
* Provide support for loadable ethernet fragmentation modules. The fragmenter library must be named
* libathena_ETHFragmenter_<name>, and must contain an initialization routine that is named
* athenaEthernetFrabmenter_<name>_Init, which is provided an allocated AthenaEthernetFragmenter instance
* that is used to maintain private instance state for the fragmentation module.
* athenaEthernetFrabmenter_<name>_Init. The init routine is provided an AthenaEthernetFragmenter
* object instance that is used to maintain private instance state for the fragmentation module.
*/
#include <config.h>
......@@ -122,15 +122,18 @@ _destroy(AthenaEthernetFragmenter **athenaEthernetFragmenter)
if ((*athenaEthernetFragmenter)->module) {
dlclose((*athenaEthernetFragmenter)->module);
}
athenaTransportLink_Release(&((*athenaEthernetFragmenter)->athenaTransportLink));
}
parcObject_ExtendPARCObject(AthenaEthernetFragmenter, _destroy, NULL, NULL, NULL, NULL, NULL, NULL);
AthenaEthernetFragmenter *
athenaEthernetFragmenter_Create(const char *fragmenterName)
athenaEthernetFragmenter_Create(AthenaTransportLink *athenaTransportLink, const char *fragmenterName)
{
AthenaEthernetFragmenter *athenaEthernetFragmenter = parcObject_CreateAndClearInstance(AthenaEthernetFragmenter);
assertNotNull(athenaEthernetFragmenter, "Could not create a new fragmenter instance.");
athenaEthernetFragmenter->athenaTransportLink = athenaTransportLink_Acquire(athenaTransportLink);
const char *moduleLibrary = _nameToLibrary(fragmenterName);
athenaEthernetFragmenter->module = dlopen(moduleLibrary, RTLD_NOW | RTLD_GLOBAL);
parcMemory_Deallocate(&moduleLibrary);
......
......@@ -71,6 +71,7 @@ typedef void (AthenaEthernetFragmenter_Fini)(AthenaEthernetFragmenter *athenaEth
// Private data for each fragmented connection
//
struct AthenaEthernetFragmenter {
AthenaTransportLink *athenaTransportLink; // link associated with fragmenter
void *module; // so library can be unloaded
AthenaEthernetFragmenter_Send *send;
AthenaEthernetFragmenter_Receive *receive;
......@@ -82,18 +83,19 @@ struct AthenaEthernetFragmenter {
* @abstract create a new fragmenter instance
* @discussion
*
* @param [in] name of new fragmenter
* @param [in] athenaTransportLink associated with the fragmenter
* @param [in] fragmenterName of new fragmenter
* @return pointer to new instance
*
* Example:
* @code
* void
* {
* AthenaEthernetFragmenter *athenaEthernetFragmenter = athenaEthernetFragmenter_Create("BEFS");
* AthenaEthernetFragmenter *athenaEthernetFragmenter = athenaEthernetFragmenter_Create(athenaTransportLink, "BEFS");
* }
* @endcode
*/
AthenaEthernetFragmenter *athenaEthernetFragmenter_Create(const char *fragmenterName);
AthenaEthernetFragmenter *athenaEthernetFragmenter_Create(AthenaTransportLink *athenaTransportLink, const char *fragmenterName);
/**
* @abstract obtain a new reference to a fragmenter instance
......
......@@ -925,7 +925,7 @@ _ETHOpen(AthenaTransportLinkModule *athenaTransportLinkModule, PARCURI *connecti
if (result && fragmenterName) {
struct _ETHLinkData *linkData = athenaTransportLink_GetPrivateData(result);
linkData->fragmenter = athenaEthernetFragmenter_Create(fragmenterName);
linkData->fragmenter = athenaEthernetFragmenter_Create(result, fragmenterName);
}
// forced IsLocal/IsNotLocal, mainly for testing
......
/*
* Copyright (c) 2015-2016, Xerox Corporation (Xerox)and Palo Alto Research Center (PARC)
* Copyright (c) 2016, Xerox Corporation (Xerox)and Palo Alto Research Center (PARC)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -26,81 +26,61 @@
*/
/**
* @author Kevin Fox, Palo Alto Research Center (Xerox PARC)
* @copyright 2015-2016, Xerox Corporation (Xerox)and Palo Alto Research Center (PARC). All rights reserved.
* @copyright 2016, Xerox Corporation (Xerox)and Palo Alto Research Center (PARC). All rights reserved.
*/
#include <config.h>
#include <LongBow/runtime.h>
#include <poll.h>
#include <fcntl.h>
#include <errno.h>
#include <netdb.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <net/ethernet.h>
#include <stdio.h>
#ifdef __linux__
#include <netinet/ether.h>
#endif
#include <parc/algol/parc_Network.h>
#include <parc/algol/parc_Deque.h>
#include <parc/algol/parc_HashCodeTable.h>
#include <parc/algol/parc_Hash.h>
#include <ccnx/forwarder/athena/athena_TransportLinkModule.h>
#include <ccnx/forwarder/athena/athena_TransportLinkModuleETH.h>
#include <ccnx/forwarder/athena/athena_EthernetFragmenter.h>
#include <ccnx/forwarder/athena/athena_Ethernet.h>
#include <ccnx/forwarder/athena/athena_TransportLinkModuleETHFragmenter_BEFS.h>
#include <ccnx/common/codec/ccnxCodec_TlvPacket.h>
#include <ccnx/common/codec/schema_v1/ccnxCodecSchemaV1_FixedHeader.h>
#define METIS_PACKET_TYPE_HOPFRAG 4
#define T_HOPFRAG_PAYLOAD 0x0005
typedef struct _BEFS_private {
uint32_t sendSequenceNumber;
uint32_t receiveSequenceNumber;
PARCDeque *fragments;
} _BEFS_private;
typedef struct hopbyhop_header {
uint8_t version;
uint8_t packetType;
uint16_t packetLength;
uint8_t blob[3];
uint8_t headerLength;
uint16_t tlvType;
uint16_t tlvLength;
} __attribute__((packed)) _HopByHopHeader;
/*
* The B bit value in the top byte of the header
*/
#define BMASK 0x40
/*
* The E bit value in the top byte of the header
* Fragmenter module supporting the point to point fragmentation described in:
*
* ICN "Begin-End" Hop by Hop Fragmentation (draft-mosko-icnrg-beginendfragment-00)
*/
#define EMASK 0x20
/*
* Sets the B flag in the header
* Private data used to sequence and reassemble fragments.
*/
#define _hopByHopHeader_SetBFlag(header) ((header)->blob[0] |= BMASK)
typedef struct _BEFS_fragmenterData {
uint32_t sendSequenceNumber;
uint32_t receiveSequenceNumber;
PARCDeque *fragments;
} _BEFS_fragmenterData;
/*
* Sets the E flag in the header
*/
#define _hopByHopHeader_SetEFlag(header) ((header)->blob[0] |= EMASK)
_BEFS_fragmenterData *
_ETH_BEFS_CreateFragmenterData()
{
_BEFS_fragmenterData *fragmenterData = parcMemory_Allocate(sizeof(_BEFS_fragmenterData));
fragmenterData->fragments = parcDeque_Create();
return fragmenterData;
}
_BEFS_private *
_BEFS_fragmenterData *
_ETH_BEFS_GetFragmenterData(AthenaEthernetFragmenter *athenaEthernetFragmenter)
{
return (_BEFS_private*)athenaEthernetFragmenter->fragmenterData;
return (_BEFS_fragmenterData*)athenaEthernetFragmenter->fragmenterData;
}
void
_ETH_BEFS_DestroyFragmenterData(AthenaEthernetFragmenter *athenaEthernetFragmenter)
{
_BEFS_fragmenterData *fragmenterData = _ETH_BEFS_GetFragmenterData(athenaEthernetFragmenter);
while (parcDeque_Size(fragmenterData->fragments) > 0) {
PARCBuffer *wireFormatBuffer = parcDeque_RemoveFirst(fragmenterData->fragments);
parcBuffer_Release(&wireFormatBuffer);
}
parcDeque_Release(&(fragmenterData->fragments));
parcMemory_Deallocate(&fragmenterData);
}
bool
......@@ -114,6 +94,9 @@ _ETH_BEFS_IsFragment(PARCBuffer *wireFormatBuffer)
return result;
}
/*
* Methods for setting up and reading information from the hop by hop header
*/
static void
_hopByHopHeader_SetPayloadLength(_HopByHopHeader *header, size_t payloadLength)
{
......@@ -145,26 +128,21 @@ _hopByHopHeader_SetSequenceNumber(_HopByHopHeader *header, uint32_t seqnum)
}
/*
* non-zero if the B flag is set
* Determine if it's a packet that we own, and if so, perform the fragmentation protocol, otherwise
* send the packet back so that it can be handled by someone else. If we return null, we've retained
* the message along with it's ownership.
*/
#define _hopByHopHeader_GetBFlag(header) ((header)->blob[0] & BMASK)
/*
* non-zero if the E flag is set
*/
#define _hopByHopHeader_GetEFlag(header) ((header)->blob[0] & EMASK)
PARCBuffer *
_ETH_BEFS_ReceiveAndReassemble(AthenaEthernetFragmenter *athenaEthernetFragmenter, PARCBuffer *wireFormatBuffer)
{
_BEFS_private *fragmenterData = _ETH_BEFS_GetFragmenterData(athenaEthernetFragmenter);
assertTrue(wireFormatBuffer != NULL, "Fragmenter reassembly called with a null buffer");
// If it's not our fragment, send it back
// If it's not a fragment type we recognize, send it back for others to process
if (!_ETH_BEFS_IsFragment(wireFormatBuffer)) {
return wireFormatBuffer;
}
_BEFS_fragmenterData *fragmenterData = _ETH_BEFS_GetFragmenterData(athenaEthernetFragmenter);
assertTrue(wireFormatBuffer != NULL, "Fragmenter reassembly called with a null buffer");
// Verify the type, and move the buffer beyond the header.
_HopByHopHeader *header = parcBuffer_Overlay(wireFormatBuffer, sizeof(_HopByHopHeader));
assertTrue(header->packetType == METIS_PACKET_TYPE_HOPFRAG, "ETH_BEFS Unknown fragment type (%d)", header->packetType);
......@@ -218,7 +196,7 @@ _ETH_BEFS_FragmentAndSend(AthenaEthernetFragmenter *athenaEthernetFragmenter,
size_t mtu, struct ether_header *etherHeader,
CCNxMetaMessage *ccnxMetaMessage)
{
_BEFS_private *fragmenterData = _ETH_BEFS_GetFragmenterData(athenaEthernetFragmenter);
_BEFS_fragmenterData *fragmenterData = _ETH_BEFS_GetFragmenterData(athenaEthernetFragmenter);
_HopByHopHeader fragmentHeader = {0};
const size_t maxPayload = mtu - sizeof(_HopByHopHeader);
_hopByHopHeader_SetBFlag(&fragmentHeader);
......@@ -270,21 +248,13 @@ _ETH_BEFS_FragmentAndSend(AthenaEthernetFragmenter *athenaEthernetFragmenter,
static void
_athenaEthernetFragmenter_BEFS_Fini(AthenaEthernetFragmenter *athenaEthernetFragmenter)
{
_BEFS_private *fragmenterData = _ETH_BEFS_GetFragmenterData(athenaEthernetFragmenter);
while (parcDeque_Size(fragmenterData->fragments) > 0) {
PARCBuffer *wireFormatBuffer = parcDeque_RemoveFirst(fragmenterData->fragments);
parcBuffer_Release(&wireFormatBuffer);
}
parcDeque_Release(&(fragmenterData->fragments));
parcMemory_Deallocate(&(fragmenterData));
_ETH_BEFS_DestroyFragmenterData(athenaEthernetFragmenter);
}
AthenaEthernetFragmenter *
athenaEthernetFragmenter_BEFS_Init(AthenaEthernetFragmenter *athenaEthernetFragmenter)
{
athenaEthernetFragmenter->fragmenterData = parcMemory_Allocate(sizeof(_BEFS_private));
_BEFS_private *fragmenterData = _ETH_BEFS_GetFragmenterData(athenaEthernetFragmenter);
fragmenterData->fragments = parcDeque_Create();
athenaEthernetFragmenter->fragmenterData = _ETH_BEFS_CreateFragmenterData();
athenaEthernetFragmenter->send = (AthenaEthernetFragmenter_Send *)_ETH_BEFS_FragmentAndSend;
athenaEthernetFragmenter->receive = (AthenaEthernetFragmenter_Receive *)_ETH_BEFS_ReceiveAndReassemble;
athenaEthernetFragmenter->fini = (AthenaEthernetFragmenter_Fini *)_athenaEthernetFragmenter_BEFS_Fini;
......
/*
* Copyright (c) 2016, Xerox Corporation (Xerox)and Palo Alto Research Center (PARC)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Patent rights are not granted under this agreement. Patent rights are
* available under FRAND terms.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL XEROX or PARC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @author Kevin Fox, Palo Alto Research Center (Xerox PARC)
* @copyright 2016, Xerox Corporation (Xerox)and Palo Alto Research Center (PARC). All rights reserved.
*/
#ifndef libathena_EthernetFragmenter_BEFS_h
#define libathena_EthernetFragmenter_BEFS_h
/*
* Fragmenter module supporting point to point fragmentation that is documented in:
*
* ICN "Begin-End" Hop by Hop Fragmentation (draft-mosko-icnrg-beginendfragment-00)
*/
// Legacy names from original Metis implementation
#define METIS_PACKET_TYPE_HOPFRAG 4
#define T_HOPFRAG_PAYLOAD 0x0005
typedef struct hopbyhop_header {
uint8_t version;
uint8_t packetType;
uint16_t packetLength;
uint8_t blob[3];
uint8_t headerLength;
uint16_t tlvType;
uint16_t tlvLength;
} __attribute__((packed)) _HopByHopHeader;
/*
* The B bit value in the top byte of the header
*/
#define BMASK 0x40
/*
* The E bit value in the top byte of the header
*/
#define EMASK 0x20
/*
* The I bit value in the top byte of the header
*/
#define IMASK 0x10
/*
* Sets the B flag in the header
*/
#define _hopByHopHeader_SetBFlag(header) ((header)->blob[0] |= BMASK)
/*
* Sets the E flag in the header
*/
#define _hopByHopHeader_SetEFlag(header) ((header)->blob[0] |= EMASK)
/*
* non-zero if the B flag is set
*/
#define _hopByHopHeader_GetBFlag(header) ((header)->blob[0] & BMASK)
/*
* non-zero if the E flag is set
*/
#define _hopByHopHeader_GetEFlag(header) ((header)->blob[0] & EMASK)
/*
* non-zero if the I flag is set
*/
#define _hopByHopHeader_GetIFlag(header) ((header)->blob[0] & IMASK)
AthenaEthernetFragmenter *athenaEthernetFragmenter_BEFS_Init(AthenaEthernetFragmenter *athenaEthernetFragmenter);
#endif // libathena_EthernetFragmenter_BEFS_h
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment