* Major tweak to the serialiser: shifted size to 32bits to handle bigger packets. This will break compatibility.

* Modified tlvitems to support future expansions.
 * added random tlv test functios.
 * added dummy Wide Directory functions to rsdir (for the future;)
 * Fixed Mutex Bug in fimonitor.
 * added netiface_test for hiberation / net change testing.



git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@1620 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2009-09-08 20:18:43 +00:00
parent 05676e4399
commit 0f99826623
19 changed files with 1588 additions and 319 deletions

View File

@ -765,10 +765,12 @@ void FileIndexMonitor::setSharedDirectories(std::list<SharedDirInfo> dirs)
closedir(dir);
}
RsStackMutex stack(fiMutex) ;/* LOCKED DIRS */
{
RsStackMutex stack(fiMutex) ;/* LOCKED DIRS */
pendingDirs = true;
pendingDirList = checkeddirs;
pendingDirs = true;
pendingDirList = checkeddirs;
}
cb->notifyListChange(NOTIFY_LIST_DIRLIST_LOCAL, 0);
}

View File

@ -20,10 +20,10 @@ UDP_OBJ = pqissludp.o
OTHER_OBJ = p3notify.o
TESTOBJ = net_test.o dht_test.o net_test1.o
TESTOBJ = net_test.o dht_test.o net_test1.o netiface_test.o
#conn_test.o
TESTS = net_test dht_test net_test1
TESTS = net_test dht_test net_test1 netiface_test
#conn_test
ifdef PQI_USE_XPGP
@ -68,6 +68,9 @@ net_test: net_test.o
net_test1: net_test1.o
$(CC) $(CFLAGS) -o net_test1 net_test1.o $(LIBS)
netiface_test: netiface_test.o
$(CC) $(CFLAGS) -o netiface_test netiface_test.o $(LIBS)
###############################################################
include $(RS_TOP_DIR)/scripts/rules.mk
###############################################################

View File

@ -0,0 +1,63 @@
/*
* libretroshare/src/pqi net_test.cc
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2007-2008 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
/******
* NETWORKING Test to check Big/Little Endian behaviour
* as well as socket behaviour
*
*/
#include "pqi/pqinetwork.h"
#include "util/rsnet.h"
#include <iostream>
#include <sstream>
bool test_iface();
int main(int argc, char **argv)
{
test_iface();
return 1;
}
/* test 1: byte manipulation */
bool test_iface()
{
struct in_addr pref_iface = getPreferredInterface();
std::list<std::string> ifaces = getLocalInterfaces();
std::list<std::string>::iterator it;
std::cerr << "test_iface()" << std::endl;
for(it = ifaces.begin(); it != ifaces.end(); it++)
{
std::cerr << "available iface: " << *it << std::endl;
}
std::cerr << "preferred " << inet_ntoa(pref_iface) << std::endl;
return true;
}

View File

@ -38,6 +38,8 @@
* #define CONFIG_DEBUG 1
***/
#define CONFIG_DEBUG 1
p3ConfigMgr::p3ConfigMgr(p3AuthMgr *am, std::string dir, std::string fname, std::string signame)
:mAuthMgr(am), basedir(dir), metafname(fname), metasigfname(signame),
mConfigSaveActive(true)

View File

@ -25,13 +25,13 @@ RSOBJ += rsstatusitems.o # RsItems
TESTOBJ = tlvbase_test.o tlvbase_test2.o tlvfileitem_test.o
TESTOBJ += tlvitems_test.o tlvstack_test.o tlvconfig_test.o
TESTOBJ += rsserial_test.o rstlvwidetest.o
TESTOBJ += rsserial_test.o rstlvwidetest.o tlvrandom_test.o
#rsbaseitem_test.o
TESTS = tlvbase_test tlvbase_test2 tlvfileitem_test
TESTS += tlvitems_test tlvstack_test tlvconfig_test
TESTS += rstlvwidetest
TESTS += rstlvwidetest tlvrandom_test
#rsserial_test
#rsbaseitem_test
@ -65,6 +65,9 @@ rsbaseitem_test : rsbaseitem_test.o
rstlvwidetest : rstlvwidetest.o
$(CC) $(CFLAGS) -o rstlvwidetest rstlvwidetest.o $(OBJ) $(LIBS)
tlvrandom_test : tlvrandom_test.o
$(CC) $(CFLAGS) -o tlvrandom_test tlvrandom_test.o $(OBJ) $(LIBS)
###############################################################
include $(RS_TOP_DIR)/scripts/rules.mk

View File

@ -78,6 +78,10 @@ std::ostream &RsDistribMsg::print(std::ostream &out, uint16_t indent)
void RsDistribSignedMsg::clear()
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSignedMsg::clear()" << std::endl;
#endif
grpId.clear();
msgId.clear();
flags = 0;
@ -114,6 +118,10 @@ std::ostream &RsDistribSignedMsg::print(std::ostream &out, uint16_t indent)
void RsDistribGrp::clear()
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribGrp::clear()" << std::endl;
#endif
grpId.clear();
timestamp = 0;
grpFlags = 0;
@ -176,6 +184,10 @@ std::ostream &RsDistribGrp::print(std::ostream &out, uint16_t indent)
void RsDistribGrpKey::clear()
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribGrpKey::clear()" << std::endl;
#endif
grpId.clear();
key.TlvClear();
}
@ -222,11 +234,21 @@ uint32_t RsDistribSerialiser::sizeGrp(RsDistribGrp *item)
/* serialise the data to the buffer */
bool RsDistribSerialiser::serialiseGrp(RsDistribGrp *item, void *data, uint32_t *pktsize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::serialiseGrp()" << std::endl;
#endif
uint32_t tlvsize = sizeGrp(item);
uint32_t offset = 0;
if (*pktsize < tlvsize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::serialiseGrp() FAIL no space" << std::endl;
#endif
return false; /* not enough space */
}
*pktsize = tlvsize;
@ -242,18 +264,42 @@ bool RsDistribSerialiser::serialiseGrp(RsDistribGrp *item, void *data, uint3
ok &= setRawUInt32(data, tlvsize, &offset, item->timestamp);
ok &= setRawUInt32(data, tlvsize, &offset, item->grpFlags);
#ifdef RSSERIAL_DEBUG
if (!ok)
std::cerr << "RsDistribSerialiser::serialiseGrp() Id/Flags NOK" << std::endl;
#endif
ok &= SetTlvWideString(data, tlvsize, &offset, TLV_TYPE_WSTR_NAME, item->grpName);
ok &= SetTlvWideString(data, tlvsize, &offset, TLV_TYPE_WSTR_COMMENT, item->grpDesc);
ok &= SetTlvWideString(data, tlvsize, &offset, TLV_TYPE_WSTR_CATEGORY, item->grpCategory);
#ifdef RSSERIAL_DEBUG
if (!ok)
std::cerr << "RsDistribSerialiser::serialiseGrp() Strings NOK" << std::endl;
#endif
ok &= setRawUInt32(data, tlvsize, &offset, item->grpControlFlags);
ok &= item->grpControlList.SetTlv(data, tlvsize, &offset);
ok &= item->grpPixmap.SetTlv(data, tlvsize, &offset);
#ifdef RSSERIAL_DEBUG
if (!ok)
std::cerr << "RsDistribSerialiser::serialiseGrp() List/Pix NOK" << std::endl;
#endif
ok &= item->adminKey.SetTlv(data, tlvsize, &offset);
#ifdef RSSERIAL_DEBUG
if (!ok)
std::cerr << "RsDistribSerialiser::serialiseGrp() AdminKey NOK" << std::endl;
#endif
ok &= item->publishKeys.SetTlv(data, tlvsize, &offset);
#ifdef RSSERIAL_DEBUG
if (!ok)
std::cerr << "RsDistribSerialiser::serialiseGrp() PubKey NOK" << std::endl;
#endif
ok &= item->adminSignature.SetTlv(data, tlvsize, &offset);
#ifdef RSSERIAL_DEBUG
if (!ok)
std::cerr << "RsDistribSerialiser::serialiseGrp() AdminSign NOK" << std::endl;
#endif
if (offset != tlvsize)
{
@ -261,12 +307,22 @@ bool RsDistribSerialiser::serialiseGrp(RsDistribGrp *item, void *data, uint3
std::cerr << "RsDistribSerialiser::serialiseGrp() Size Error! " << std::endl;
}
#ifdef RSSERIAL_DEBUG
if (!ok)
{
std::cerr << "RsDistribSerialiser::serialiseGrp() NOK" << std::endl;
}
#endif
return ok;
}
RsDistribGrp *RsDistribSerialiser::deserialiseGrp(void *data, uint32_t *pktsize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::deserialiseGrp()" << std::endl;
#endif
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
@ -278,11 +334,19 @@ RsDistribGrp *RsDistribSerialiser::deserialiseGrp(void *data, uint32_t *pktsize)
(RS_SERVICE_TYPE_DISTRIB != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_DISTRIB_GRP != getRsItemSubType(rstype)))
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::deserialiseGrp() FAIL wrong type" << std::endl;
#endif
return NULL; /* wrong type */
}
if (*pktsize < rssize) /* check size */
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::deserialiseGrp() FAIL wrong size" << std::endl;
#endif
return NULL; /* not enough data */
}
/* set the packet length */
*pktsize = rssize;
@ -316,6 +380,9 @@ RsDistribGrp *RsDistribSerialiser::deserialiseGrp(void *data, uint32_t *pktsize)
if (offset != rssize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::deserialiseGrp() FAIL size mismatch" << std::endl;
#endif
/* error */
delete item;
return NULL;
@ -323,6 +390,9 @@ RsDistribGrp *RsDistribSerialiser::deserialiseGrp(void *data, uint32_t *pktsize)
if (!ok)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::deserialiseGrp() NOK" << std::endl;
#endif
delete item;
return NULL;
}
@ -344,25 +414,52 @@ uint32_t RsDistribSerialiser::sizeGrpKey(RsDistribGrpKey *item)
/* serialise the data to the buffer */
bool RsDistribSerialiser::serialiseGrpKey(RsDistribGrpKey *item, void *data, uint32_t *pktsize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::serialiseGrpKey()" << std::endl;
#endif
/* error */
uint32_t tlvsize = sizeGrpKey(item);
uint32_t offset = 0;
if (*pktsize < tlvsize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::serialiseGrpKey() FAIL no space" << std::endl;
#endif
return false; /* not enough space */
}
*pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
#ifdef RSSERIAL_DEBUG
if (!ok)
{
std::cerr << "RsDistribSerialiser::serialiseGrpKey() HEADER FAILED" << std::endl;
}
#endif
/* skip the header */
offset += 8;
/* RsDistribGrp */
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_GROUPID, item->grpId);
#ifdef RSSERIAL_DEBUG
if (!ok)
{
std::cerr << "RsDistribSerialiser::serialiseGrpKey() GROUPID FAILED" << std::endl;
}
#endif
ok &= item->key.SetTlv(data, tlvsize, &offset);
#ifdef RSSERIAL_DEBUG
if (!ok)
{
std::cerr << "RsDistribSerialiser::serialiseGrpKey() KEY FAILED" << std::endl;
}
#endif
if (offset != tlvsize)
{
@ -370,12 +467,22 @@ bool RsDistribSerialiser::serialiseGrpKey(RsDistribGrpKey *item, void *data,
std::cerr << "RsDistribSerialiser::serialiseGrpKey() Size Error! " << std::endl;
}
#ifdef RSSERIAL_DEBUG
if (!ok)
{
std::cerr << "RsDistribSerialiser::serialiseGrpKey() NOK" << std::endl;
}
#endif
return ok;
}
RsDistribGrpKey *RsDistribSerialiser::deserialiseGrpKey(void *data, uint32_t *pktsize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::deserialiseGrpKey()" << std::endl;
#endif
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
@ -387,11 +494,19 @@ RsDistribGrpKey *RsDistribSerialiser::deserialiseGrpKey(void *data, uint32_t *pk
(RS_SERVICE_TYPE_DISTRIB != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_DISTRIB_GRP_KEY != getRsItemSubType(rstype)))
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::deserialiseGrpKey() FAIL wrong type" << std::endl;
#endif
return NULL; /* wrong type */
}
if (*pktsize < rssize) /* check size */
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::deserialiseGrpKey() FAIL no space" << std::endl;
#endif
return NULL; /* not enough data */
}
/* set the packet length */
*pktsize = rssize;
@ -411,6 +526,9 @@ RsDistribGrpKey *RsDistribSerialiser::deserialiseGrpKey(void *data, uint32_t *pk
if (offset != rssize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::deserialiseGrpKey() FAIL size mismatch" << std::endl;
#endif
/* error */
delete item;
return NULL;
@ -418,6 +536,9 @@ RsDistribGrpKey *RsDistribSerialiser::deserialiseGrpKey(void *data, uint32_t *pk
if (!ok)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::deserialiseGrpKey() FAIL not Okay" << std::endl;
#endif
delete item;
return NULL;
}
@ -445,11 +566,19 @@ uint32_t RsDistribSerialiser::sizeSignedMsg(RsDistribSignedMsg *item)
/* serialise the data to the buffer */
bool RsDistribSerialiser::serialiseSignedMsg(RsDistribSignedMsg *item, void *data, uint32_t *pktsize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::serialiseSignedMsg()" << std::endl;
#endif
uint32_t tlvsize = sizeSignedMsg(item);
uint32_t offset = 0;
if (*pktsize < tlvsize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::serialiseSignedMsg() FAIL no space" << std::endl;
#endif
return false; /* not enough space */
}
*pktsize = tlvsize;
@ -474,16 +603,28 @@ bool RsDistribSerialiser::serialiseSignedMsg(RsDistribSignedMsg *item, void
if (offset != tlvsize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::serialiseSignedMsg() FAIL Size Error! " << std::endl;
#endif
ok = false;
std::cerr << "RsDistribSerialiser::serialiseSignedMsg() Size Error! " << std::endl;
}
#ifdef RSSERIAL_DEBUG
if (!ok)
{
std::cerr << "RsDistribSerialiser::serialiseSignedMsg() NOK" << std::endl;
}
#endif
return ok;
}
RsDistribSignedMsg *RsDistribSerialiser::deserialiseSignedMsg(void *data, uint32_t *pktsize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::deserialiseSignedMsg()" << std::endl;
#endif
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
@ -495,11 +636,19 @@ RsDistribSignedMsg *RsDistribSerialiser::deserialiseSignedMsg(void *data, uint32
(RS_SERVICE_TYPE_DISTRIB != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_DISTRIB_SIGNED_MSG != getRsItemSubType(rstype)))
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::deserialiseSignedMsg() Wrong Type" << std::endl;
#endif
return NULL; /* wrong type */
}
if (*pktsize < rssize) /* check size */
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::deserialiseSignedMsg() Wrong Size" << std::endl;
#endif
return NULL; /* not enough data */
}
/* set the packet length */
*pktsize = rssize;
@ -526,6 +675,9 @@ RsDistribSignedMsg *RsDistribSerialiser::deserialiseSignedMsg(void *data, uint32
if (offset != rssize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::deserialiseSignedMsg() size mismatch" << std::endl;
#endif
/* error */
delete item;
return NULL;
@ -533,6 +685,9 @@ RsDistribSignedMsg *RsDistribSerialiser::deserialiseSignedMsg(void *data, uint32
if (!ok)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::deserialiseSignedMsg() NOK" << std::endl;
#endif
delete item;
return NULL;
}
@ -569,6 +724,9 @@ uint32_t RsDistribSerialiser::size(RsItem *i)
bool RsDistribSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::serialise()" << std::endl;
#endif
RsDistribGrp *dg;
RsDistribGrpKey *dgk;
RsDistribSignedMsg *dsm;
@ -590,6 +748,9 @@ bool RsDistribSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize
RsItem *RsDistribSerialiser::deserialise(void *data, uint32_t *pktsize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsDistribSerialiser::deserialise()" << std::endl;
#endif
/* get the type and size */
uint32_t rstype = getRsItemId(data);

View File

@ -29,37 +29,6 @@
#include "serialiser/rstlvbase.h"
#include "serialiser/rsbaseserial.h"
/*******************************************************************
* These are the general TLV (un)packing routines.
*
* Data is Serialised into the following format
*
* -----------------------------------------
* | TLV TYPE (2 bytes)| TLV LEN (2 bytes) |
* -----------------------------------------
* | |
* | Data .... |
* | |
* -----------------------------------------
*
* Size is the total size of the TLV Field (including the 4 byte header)
*
* Like the lowlevel packing routines. They are usually
* created in pairs - one to pack the data, the other to unpack.
*
* GetTlvXXX(void *data, uint32_t size, uint32_t *offset, XXX *out);
* SetTlvXXX(void *data, uint32_t size, uint32_t *offset, XXX *in);
*
*
* data - the base pointer to the serialised data.
* size - size of the memory pointed to by data.
* *offset - where we want to (un)pack the data.
* This is incremented by the datasize.
*
* *in / *out - the data to (un)pack.
*
******************************************************************/
//*********************
// A facility func
@ -71,21 +40,18 @@ inline void* right_shift_void_pointer(void* p, uint32_t len) {
#define TLV_BASE_DEBUG 1
const uint32_t TYPE_FIELD_BYTES = 2;
/**** Basic TLV Functions ****/
uint16_t GetTlvSize(void *data) {
if (!data)
return 0;
uint16_t len;
uint32_t len;
void * from =right_shift_void_pointer(data, sizeof(uint16_t));
void * from =right_shift_void_pointer(data, TLV_HEADER_TYPE_SIZE);
memcpy((void *)&len, from , sizeof(uint16_t));
memcpy((void *)&len, from , TLV_HEADER_LEN_SIZE);
len = ntohs(len);
len = ntohl(len);
return len;
}
@ -96,7 +62,7 @@ uint16_t GetTlvType(void *data) {
uint16_t type;
memcpy((void*)&type, data, TYPE_FIELD_BYTES);
memcpy((void*)&type, data, TLV_HEADER_TYPE_SIZE);
type = ntohs(type);
@ -106,48 +72,95 @@ uint16_t GetTlvType(void *data) {
//tested
bool SetTlvBase(void *data, uint32_t size, uint32_t *offset, uint16_t type,
uint16_t len) {
uint32_t len) {
if (!data)
return false;
if (!offset)
return false;
if (size < *offset +4)
if (size < *offset + TLV_HEADER_SIZE)
return false;
uint16_t type_n = htons(type);
//copy type_n to (data+*offset)
void* to = right_shift_void_pointer(data, *offset);
memcpy(to , (void*)&type_n, sizeof(uint16_t));
memcpy(to , (void*)&type_n, TLV_HEADER_TYPE_SIZE);
uint16_t len_n =htons(len);
uint32_t len_n =htonl(len);
//copy len_n to (data + *offset +2)
to = right_shift_void_pointer(to, sizeof(uint16_t));
memcpy((void *)to, (void*)&len_n, sizeof(uint16_t));
to = right_shift_void_pointer(to, TLV_HEADER_TYPE_SIZE);
memcpy((void *)to, (void*)&len_n, TLV_HEADER_LEN_SIZE);
*offset += sizeof(uint16_t)*2;
*offset += TLV_HEADER_SIZE;
return true;
}
bool SetTlvType(void *data, uint32_t size, uint16_t type)
{
if (!data)
return false;
if(size < TLV_HEADER_SIZE )
return false;
uint16_t type_n = htons(type);
memcpy(data , (void*)&type_n, TLV_HEADER_TYPE_SIZE);
return true;
}
//tested
bool SetTlvSize(void *data, uint32_t size, uint16_t len) {
bool SetTlvSize(void *data, uint32_t size, uint32_t len) {
if (!data)
return false;
if(size < sizeof(uint16_t)*2 )
if(size < TLV_HEADER_SIZE )
return false;
uint16_t len_n = htons(len);
uint32_t len_n = htonl(len);
void * to = (void*)((uint8_t *) data + sizeof(uint16_t));
void * to = (void*)((uint8_t *) data + TLV_HEADER_TYPE_SIZE);
memcpy(to, (void*) &len_n, sizeof(uint16_t));
memcpy(to, (void*) &len_n, TLV_HEADER_LEN_SIZE);
return true;
}
/* Step past unknown TLV TYPE */
bool SkipUnknownTlv(void *data, uint32_t size, uint32_t *offset)
{
if (!data)
return false;
if (size < *offset + TLV_HEADER_SIZE)
return false;
/* extract the type and size */
void *tlvstart = right_shift_void_pointer(data, *offset);
uint16_t tlvtype = GetTlvType(tlvstart);
uint32_t tlvsize = GetTlvSize(tlvstart);
/* check that there is size */
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
{
#ifdef TLV_BASE_DEBUG
std::cerr << "SkipUnknownTlv() FAILED - not enough space." << std::endl;
std::cerr << "SkipUnknownTlv() size: " << size << std::endl;
std::cerr << "SkipUnknownTlv() tlvsize: " << tlvsize << std::endl;
std::cerr << "SkipUnknownTlv() tlvend: " << tlvend << std::endl;
#endif
return false;
}
bool ok = true;
/* step past this tlv item */
*offset = tlvend;
return ok;
}
/**** Generic TLV Functions ****
* This have the same data (int or string for example),
* but they can have different types eg. a string could represent a name or a path,
@ -159,7 +172,7 @@ bool SetTlvUInt32(void *data, uint32_t size, uint32_t *offset, uint16_t type,
{
if (!data)
return false;
uint16_t tlvsize = GetTlvUInt32Size(); /* this will always be 8 bytes */
uint32_t tlvsize = GetTlvUInt32Size(); /* this will always be 8 bytes */
uint32_t tlvend = *offset + tlvsize; /* where the data will extend to */
if (size < tlvend)
{
@ -207,13 +220,13 @@ bool GetTlvUInt32(void *data, uint32_t size, uint32_t *offset,
if (!data)
return false;
if (size < *offset + 4)
if (size < *offset + TLV_HEADER_SIZE)
return false;
/* extract the type and size */
void *tlvstart = right_shift_void_pointer(data, *offset);
uint16_t tlvtype = GetTlvType(tlvstart);
uint16_t tlvsize = GetTlvSize(tlvstart);
uint32_t tlvsize = GetTlvSize(tlvstart);
/* check that there is size */
uint32_t tlvend = *offset + tlvsize;
@ -238,7 +251,7 @@ bool GetTlvUInt32(void *data, uint32_t size, uint32_t *offset,
return false;
}
*offset += 4; /* step past header */
*offset += TLV_HEADER_SIZE; /* step past header */
bool ok = true;
ok &= getRawUInt32(data, tlvend, offset, in);
@ -248,20 +261,20 @@ bool GetTlvUInt32(void *data, uint32_t size, uint32_t *offset,
uint32_t GetTlvUInt64Size() {
return 4 + 8;
return TLV_HEADER_SIZE + 8;
}
uint32_t GetTlvUInt32Size() {
return 4 + 4;
return TLV_HEADER_SIZE + 4;
}
uint32_t GetTlvUInt16Size() {
return 4 + sizeof(uint16_t);
return TLV_HEADER_SIZE + sizeof(uint16_t);
}
uint32_t GetTlvUInt8Size() {
return 4 + sizeof(uint8_t);
return TLV_HEADER_SIZE + sizeof(uint8_t);
}
@ -271,7 +284,7 @@ bool SetTlvUInt64(void *data, uint32_t size, uint32_t *offset, uint16_t type,
{
if (!data)
return false;
uint16_t tlvsize = GetTlvUInt64Size();
uint32_t tlvsize = GetTlvUInt64Size();
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
{
@ -317,13 +330,13 @@ bool GetTlvUInt64(void *data, uint32_t size, uint32_t *offset,
if (!data)
return false;
if (size < *offset + 4)
if (size < *offset + TLV_HEADER_SIZE)
return false;
/* extract the type and size */
void *tlvstart = right_shift_void_pointer(data, *offset);
uint16_t tlvtype = GetTlvType(tlvstart);
uint16_t tlvsize = GetTlvSize(tlvstart);
uint32_t tlvsize = GetTlvSize(tlvstart);
/* check that there is size */
uint32_t tlvend = *offset + tlvsize;
@ -348,7 +361,7 @@ bool GetTlvUInt64(void *data, uint32_t size, uint32_t *offset,
return false;
}
*offset += 4; /* step past header */
*offset += TLV_HEADER_SIZE; /* step past header */
bool ok = true;
ok &= getRawUInt64(data, tlvend, offset, in);
@ -362,7 +375,7 @@ bool SetTlvString(void *data, uint32_t size, uint32_t *offset,
{
if (!data)
return false;
uint16_t tlvsize = GetTlvStringSize(out);
uint32_t tlvsize = GetTlvStringSize(out);
uint32_t tlvend = *offset + tlvsize; /* where the data will extend to */
if (size < tlvend)
@ -381,7 +394,7 @@ bool SetTlvString(void *data, uint32_t size, uint32_t *offset,
void * to = right_shift_void_pointer(data, *offset);
uint16_t strlen = tlvsize - 4;
uint16_t strlen = tlvsize - TLV_HEADER_SIZE;
memcpy(to, out.c_str(), strlen);
*offset += strlen;
@ -396,7 +409,7 @@ bool GetTlvString(void *data, uint32_t size, uint32_t *offset,
if (!data)
return false;
if (size < *offset + 4)
if (size < *offset + TLV_HEADER_SIZE)
{
#ifdef TLV_BASE_DEBUG
std::cerr << "GetTlvString() FAILED - not enough space" << std::endl;
@ -409,7 +422,7 @@ bool GetTlvString(void *data, uint32_t size, uint32_t *offset,
/* extract the type and size */
void *tlvstart = right_shift_void_pointer(data, *offset);
uint16_t tlvtype = GetTlvType(tlvstart);
uint16_t tlvsize = GetTlvSize(tlvstart);
uint32_t tlvsize = GetTlvSize(tlvstart);
/* check that there is size */
uint32_t tlvend = *offset + tlvsize;
@ -435,7 +448,7 @@ bool GetTlvString(void *data, uint32_t size, uint32_t *offset,
}
char *strdata = (char *) right_shift_void_pointer(tlvstart, 4);
uint16_t strsize = tlvsize - 4; /* remove the header */
uint16_t strsize = tlvsize - TLV_HEADER_SIZE; /* remove the header */
in = std::string(strdata, strsize);
*offset += tlvsize; /* step along */
@ -443,7 +456,7 @@ bool GetTlvString(void *data, uint32_t size, uint32_t *offset,
}
uint32_t GetTlvStringSize(const std::string &in) {
return 4 + in.size();
return TLV_HEADER_SIZE + in.size();
}
@ -458,7 +471,7 @@ bool SetTlvWideString(void *data, uint32_t size, uint32_t *offset,
{
if (!data)
return false;
uint16_t tlvsize = GetTlvWideStringSize(out);
uint32_t tlvsize = GetTlvWideStringSize(out);
uint32_t tlvend = *offset + tlvsize; /* where the data will extend to */
if (size < tlvend)
@ -475,10 +488,10 @@ bool SetTlvWideString(void *data, uint32_t size, uint32_t *offset,
bool ok = true;
ok &= SetTlvBase(data, tlvend, offset, type, tlvsize);
uint16_t strlen = out.length();
uint32_t strlen = out.length();
/* Must convert manually to ensure its always the same! */
for(uint16_t i = 0; i < strlen; i++)
for(uint32_t i = 0; i < strlen; i++)
{
uint32_t widechar = out[i];
ok &= setRawUInt32(data, tlvend, offset, widechar);
@ -493,7 +506,7 @@ bool GetTlvWideString(void *data, uint32_t size, uint32_t *offset,
if (!data)
return false;
if (size < *offset + 4)
if (size < *offset + TLV_HEADER_SIZE)
{
#ifdef TLV_BASE_DEBUG
std::cerr << "GetTlvWideString() FAILED - not enough space" << std::endl;
@ -506,7 +519,7 @@ bool GetTlvWideString(void *data, uint32_t size, uint32_t *offset,
/* extract the type and size */
void *tlvstart = right_shift_void_pointer(data, *offset);
uint16_t tlvtype = GetTlvType(tlvstart);
uint16_t tlvsize = GetTlvSize(tlvstart);
uint32_t tlvsize = GetTlvSize(tlvstart);
/* check that there is size */
uint32_t tlvend = *offset + tlvsize;
@ -534,11 +547,11 @@ bool GetTlvWideString(void *data, uint32_t size, uint32_t *offset,
bool ok = true;
/* remove the header, calc string length */
*offset += 4;
uint16_t strlen = (tlvsize - 4) / RS_WCHAR_SIZE;
*offset += TLV_HEADER_SIZE;
uint16_t strlen = (tlvsize - TLV_HEADER_SIZE) / RS_WCHAR_SIZE;
/* Must convert manually to ensure its always the same! */
for(uint16_t i = 0; i < strlen; i++)
for(uint32_t i = 0; i < strlen; i++)
{
uint32_t widechar;
ok &= getRawUInt32(data, tlvend, offset, &widechar);
@ -548,7 +561,7 @@ bool GetTlvWideString(void *data, uint32_t size, uint32_t *offset,
}
uint32_t GetTlvWideStringSize(std::wstring &in) {
return 4 + in.size() * RS_WCHAR_SIZE;
return TLV_HEADER_SIZE + in.size() * RS_WCHAR_SIZE;
}
@ -557,7 +570,7 @@ bool SetTlvIpAddrPortV4(void *data, uint32_t size, uint32_t *offset,
if (!data)
return false;
uint16_t tlvsize = GetTlvIpAddrPortV4Size();
uint32_t tlvsize = GetTlvIpAddrPortV4Size();
uint32_t tlvend = *offset + tlvsize; /* where the data will extend to */
if (size < tlvend)
@ -589,7 +602,7 @@ bool GetTlvIpAddrPortV4(void *data, uint32_t size, uint32_t *offset,
if (!data)
return false;
if (size < *offset + 4)
if (size < *offset + TLV_HEADER_SIZE)
{
#ifdef TLV_BASE_DEBUG
std::cerr << "GetIpAddrPortV4() FAILED - not enough space" << std::endl;
@ -602,7 +615,7 @@ bool GetTlvIpAddrPortV4(void *data, uint32_t size, uint32_t *offset,
/* extract the type and size */
void *tlvstart = right_shift_void_pointer(data, *offset);
uint16_t tlvtype = GetTlvType(tlvstart);
uint16_t tlvsize = GetTlvSize(tlvstart);
uint32_t tlvsize = GetTlvSize(tlvstart);
/* check that there is size */
uint32_t tlvend = *offset + tlvsize;
@ -627,7 +640,7 @@ bool GetTlvIpAddrPortV4(void *data, uint32_t size, uint32_t *offset,
return false;
}
*offset += 4; /* skip header */
*offset += TLV_HEADER_SIZE; /* skip header */
bool ok = true;
@ -646,6 +659,6 @@ bool GetTlvIpAddrPortV4(void *data, uint32_t size, uint32_t *offset,
}
uint32_t GetTlvIpAddrPortV4Size() {
return 4 + 4 + 2; /* header + 4 (IP) + 2 (Port) */
return TLV_HEADER_SIZE + 4 + 2; /* header + 4 (IP) + 2 (Port) */
}

View File

@ -33,13 +33,17 @@
* Data is Serialised into the following format
*
* -----------------------------------------
* | TLV TYPE (2 bytes)| TLV LEN (2 bytes) |
* | TLV TYPE (2 bytes) | TLV LEN (4 bytes)|
* -----------------------------------------
* | |
* | Data .... |
* | |
* -----------------------------------------
*
* Originally TLV TYPE = 2 bytes, and TLV LEN = 2 bytes.
* However with HTML and WSTRINGS the 64K Limit becomes limiting.
* The TLV LEN = 4 bytes now!
*
* Size is the total size of the TLV Field (including the 4 byte header)
*
* Like the lowlevel packing routines. They are usually
@ -56,20 +60,6 @@
*
* *in / *out - the data to (un)pack.
*
*
* BIG TLV Fields have now been added.
* If the Tlv Type & TLV_BIGLEN_BIT
* ---------------------------------------------------------
* | TLV TYPE (2 bytes)| TLV LEN (4 bytes) |
* ---------------------------------------------------------
* | |
* | Data .... |
* | |
* ---------------------------------------------------------
*
*
*
*
******************************************************************/
#include <stdlib.h>
@ -109,6 +99,12 @@
/* 0b 1001 XXXX XXXX XXXX Compound */
/* TLV HEADER SIZE (Reference) *******************************/
const uint32_t TLV_HEADER_TYPE_SIZE = 2;
const uint32_t TLV_HEADER_LEN_SIZE = 4;
const uint32_t TLV_HEADER_SIZE = TLV_HEADER_TYPE_SIZE + TLV_HEADER_LEN_SIZE;
/* TLV HEADER SIZE (Reference) *******************************/
const uint16_t TLV_TYPE_UINT8_SERID = 0x0010;
@ -194,7 +190,9 @@ const uint16_t TLV_TYPE_WKEYVALUE = 0x1012;
const uint16_t TLV_TYPE_KEYVALUESET = 0x1011;
const uint16_t TLV_TYPE_WKEYVALUESET = 0x1013;
const uint16_t TLV_TYPE_PEERSET = 0x1020;
const uint16_t TLV_TYPE_STRINGSET = 0x1020; /* dummy non-existant */
const uint16_t TLV_TYPE_PEERSET = 0x1021;
const uint16_t TLV_TYPE_HASHSET = 0x1022;
const uint16_t TLV_TYPE_SERVICESET = 0x1030;
const uint16_t TLV_TYPE_SECURITYKEY = 0x1040;
@ -208,9 +206,12 @@ const uint16_t TLV_TYPE_IMAGE = 0x1060;
/**** Basic TLV Functions ****/
uint16_t GetTlvSize(void *data);
uint16_t GetTlvType(void *data);
bool SetTlvBase(void *data, uint32_t size, uint32_t *offset, uint16_t type, uint16_t len);
bool SetTlvSize(void *data, uint32_t size, uint16_t len);
bool SetTlvBase(void *data, uint32_t size, uint32_t *offset, uint16_t type, uint32_t len);
bool SetTlvSize(void *data, uint32_t size, uint32_t len);
bool SetTlvType(void *data, uint32_t size, uint16_t type);
/* skip past the unknown tlv elements */
bool SkipUnknownTlv(void *data, uint32_t size, uint32_t *offset);
/**** Generic TLV Functions ****
* This have the same data (int or string for example),

View File

@ -44,15 +44,17 @@ void RsTlvFileItem::TlvClear()
{
filesize = 0;
hash = "";
name = "";
path = "";
name.clear();
path.clear();
pop = 0;
age = 0;
piecesize = 0;
hashset.TlvClear();
}
uint16_t RsTlvFileItem::TlvSize()
uint32_t RsTlvFileItem::TlvSize()
{
uint32_t s = 4; /* header */
uint32_t s = TLV_HEADER_SIZE; /* header */
s += 8; /* filesize */
s += GetTlvStringSize(hash);
#ifdef TLV_FI_DEBUG
@ -93,6 +95,22 @@ uint16_t RsTlvFileItem::TlvSize()
#endif
}
if (piecesize != 0)
{
s += GetTlvUInt32Size();
#ifdef TLV_FI_DEBUG
std::cerr << "RsTlvFileItem::TlvSize() 4 + PieceSize: " << s << std::endl;
#endif
}
if (hashset.ids.size() != 0)
{
s += hashset.TlvSize();
#ifdef TLV_FI_DEBUG
std::cerr << "RsTlvFileItem::TlvSize() 4 + HashSet: " << s << std::endl;
#endif
}
#ifdef TLV_FI_DEBUG
std::cerr << "RsTlvFileItem::TlvSize() Total: " << s << std::endl;
#endif
@ -104,7 +122,7 @@ uint16_t RsTlvFileItem::TlvSize()
bool RsTlvFileItem::SetTlv(void *data, uint32_t size, uint32_t *offset)
{
/* must check sizes */
uint16_t tlvsize = TlvSize();
uint32_t tlvsize = TlvSize();
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
@ -209,6 +227,30 @@ bool RsTlvFileItem::SetTlv(void *data, uint32_t size, uint32_t *offset)
std::cerr << std::endl;
#endif
if (piecesize != 0)
ok &= SetTlvUInt32(data, tlvend, offset, TLV_TYPE_UINT32_SIZE, piecesize);
#ifdef TLV_FI_DEBUG
if (!ok)
{
std::cerr << "RsTlvFileItem::SetTlv() Setting Option:piecesize Failed (or earlier)" << std::endl;
}
std::cerr << "RsTlvFileItem::SetTlv() Post PieceSize:" << std::endl;
std::cerr << "RsTlvFileItem::SetTlv() Data: " << data << " size: " << size << " offset: " << *offset;
std::cerr << std::endl;
#endif
if (hashset.ids.size() != 0)
ok &= hashset.SetTlv(data, tlvend, offset);
#ifdef TLV_FI_DEBUG
if (!ok)
{
std::cerr << "RsTlvFileItem::SetTlv() Setting Option:hashset Failed (or earlier)" << std::endl;
}
std::cerr << "RsTlvFileItem::SetTlv() Post HashSet:" << std::endl;
std::cerr << "RsTlvFileItem::SetTlv() Data: " << data << " size: " << size << " offset: " << *offset;
std::cerr << std::endl;
#endif
#ifdef TLV_FI_DEBUG
@ -224,7 +266,7 @@ bool RsTlvFileItem::SetTlv(void *data, uint32_t size, uint32_t *offset)
bool RsTlvFileItem::GetTlv(void *data, uint32_t size, uint32_t *offset)
{
uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
uint16_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend) /* check size */
@ -239,7 +281,7 @@ bool RsTlvFileItem::GetTlv(void *data, uint32_t size, uint32_t *offset)
TlvClear();
/* skip the header */
(*offset) += 4;
(*offset) += TLV_HEADER_SIZE;
/* get mandatory parts first */
ok &= getRawUInt64(data, tlvend, offset, &filesize);
@ -264,14 +306,37 @@ bool RsTlvFileItem::GetTlv(void *data, uint32_t size, uint32_t *offset)
case TLV_TYPE_UINT32_AGE:
ok &= GetTlvUInt32(data, tlvend, offset, TLV_TYPE_UINT32_AGE, &age);
break;
case TLV_TYPE_UINT32_SIZE:
ok &= GetTlvUInt32(data, tlvend, offset, TLV_TYPE_UINT32_SIZE, &piecesize);
break;
case TLV_TYPE_HASHSET:
ok &= hashset.GetTlv(data, tlvend, offset);
break;
default:
ok = false;
ok &= SkipUnknownTlv(data, tlvend, offset);
break;
}
if (!ok)
{
return false;
break;
}
}
/***************************************************************************
* NB: extra components could be added (for future expansion of the type).
* or be present (if this code is reading an extended version).
*
* We must chew up the extra characters to conform with TLV specifications
***************************************************************************/
if (*offset != tlvend)
{
#ifdef TLV_DEBUG
std::cerr << "RsTlvFileItem::GetTlv() Warning extra bytes at end of item";
std::cerr << std::endl;
#endif
*offset = tlvend;
}
return ok;
}
@ -294,12 +359,12 @@ std::ostream &RsTlvFileItem::print(std::ostream &out, uint16_t indent)
if (name.length() > 0)
{
printIndent(out, int_Indent);
out << "Name: " << name << std::endl;
out << "Name : " << name << std::endl;
}
if (path.length() > 0)
{
printIndent(out, int_Indent);
out << "Path: " << path << std::endl;
out << "Path : " << path << std::endl;
}
if (pop != 0)
{
@ -311,6 +376,15 @@ std::ostream &RsTlvFileItem::print(std::ostream &out, uint16_t indent)
printIndent(out, int_Indent);
out << "Age: " << age << std::endl;
}
if (piecesize != 0)
{
printIndent(out, int_Indent);
out << "PieceSize: " << piecesize << std::endl;
}
if (hashset.ids.size() != 0)
{
hashset.print(out, int_Indent);
}
printEnd(out, "RsTlvFileItem", indent);
@ -327,9 +401,9 @@ void RsTlvFileSet::TlvClear()
items.clear();
}
uint16_t RsTlvFileSet::TlvSize()
uint32_t RsTlvFileSet::TlvSize()
{
uint32_t s = 4; /* header */
uint32_t s = TLV_HEADER_SIZE; /* header */
/* first determine the total size of RstlvFileItems in list */
@ -356,7 +430,7 @@ uint16_t RsTlvFileSet::TlvSize()
bool RsTlvFileSet::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
/* must check sizes */
uint16_t tlvsize = TlvSize();
uint32_t tlvsize = TlvSize();
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
@ -391,7 +465,7 @@ bool RsTlvFileSet::SetTlv(void *data, uint32_t size, uint32_t *offset) /* se
bool RsTlvFileSet::GetTlv(void *data, uint32_t size, uint32_t *offset)
{
if (size < *offset + 4)
if (size < *offset + TLV_HEADER_SIZE)
return false;
uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
@ -410,7 +484,7 @@ bool RsTlvFileSet::GetTlv(void *data, uint32_t size, uint32_t *offset)
TlvClear();
/* skip the header */
(*offset) += 4;
(*offset) += TLV_HEADER_SIZE;
/* while there is more TLV */
while((*offset) + 2 < tlvend)
@ -439,15 +513,30 @@ bool RsTlvFileSet::GetTlv(void *data, uint32_t size, uint32_t *offset)
else
{
/* unknown subtype -> error */
ok = false;
ok &= SkipUnknownTlv(data, tlvend, offset);
}
if (!ok)
{
return false;
break;
}
}
/***************************************************************************
* NB: extra components could be added (for future expansion of the type).
* or be present (if this code is reading an extended version).
*
* We must chew up the extra characters to conform with TLV specifications
***************************************************************************/
if (*offset != tlvend)
{
#ifdef TLV_DEBUG
std::cerr << "RsTlvFileSet::GetTlv() Warning extra bytes at end of item";
std::cerr << std::endl;
#endif
*offset = tlvend;
}
return ok;
}
@ -506,9 +595,9 @@ void RsTlvFileData::TlvClear()
}
uint16_t RsTlvFileData::TlvSize()
uint32_t RsTlvFileData::TlvSize()
{
uint32_t s = 4; /* header */
uint32_t s = TLV_HEADER_SIZE; /* header */
/* collect sizes for both uInts and data length */
s+= file.TlvSize();
@ -522,7 +611,7 @@ uint16_t RsTlvFileData::TlvSize()
bool RsTlvFileData::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
/* must check sizes */
uint16_t tlvsize = TlvSize();
uint32_t tlvsize = TlvSize();
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
@ -546,7 +635,7 @@ bool RsTlvFileData::SetTlv(void *data, uint32_t size, uint32_t *offset) /* seria
bool RsTlvFileData::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
if (size < *offset + 4)
if (size < *offset + TLV_HEADER_SIZE)
{
return false;
}
@ -567,13 +656,29 @@ bool RsTlvFileData::GetTlv(void *data, uint32_t size, uint32_t *offset) /* seria
TlvClear();
/* skip the header */
(*offset) += 4;
(*offset) += TLV_HEADER_SIZE;
ok &= file.GetTlv(data, size, offset);
ok &= GetTlvUInt64(data,size,offset,
TLV_TYPE_UINT64_OFFSET,&file_offset);
ok &= binData.GetTlv(data, size, offset);
/***************************************************************************
* NB: extra components could be added (for future expansion of the type).
* or be present (if this code is reading an extended version).
*
* We must chew up the extra characters to conform with TLV specifications
***************************************************************************/
if (*offset != tlvend)
{
#ifdef TLV_DEBUG
std::cerr << "RsTlvFileData::GetTlv() Warning extra bytes at end of item";
std::cerr << std::endl;
#endif
*offset = tlvend;
}
return ok;
}

View File

@ -31,7 +31,7 @@
#include "serialiser/rsbaseserial.h"
/***
* #define TLV_FI_DEBUG 1
* #define TLV_IMG_DEBUG 1
**/
/************************************* RsTlvImage ************************************/
@ -49,9 +49,9 @@ void RsTlvImage::TlvClear()
}
uint16_t RsTlvImage::TlvSize()
uint32_t RsTlvImage::TlvSize()
{
uint32_t s = 4; /* header */
uint32_t s = TLV_HEADER_SIZE; /* header */
/* collect sizes for both uInts and data length */
s+= 4;
@ -63,21 +63,45 @@ uint16_t RsTlvImage::TlvSize()
bool RsTlvImage::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
#ifdef TLV_IMG_DEBUG
std::cerr << "RsTlvImage::SetTlv()" << std::endl;
#endif
/* must check sizes */
uint16_t tlvsize = TlvSize();
uint32_t tlvsize = TlvSize();
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
{
#ifdef TLV_IMG_DEBUG
std::cerr << "RsTlvImage::SetTlv() no space" << std::endl;
#endif
return false; /* not enough space */
}
bool ok = true;
/* start at data[offset] */
ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_IMAGE , tlvsize);
#ifdef TLV_IMG_DEBUG
if (!ok)
std::cerr << "RsTlvImage::SetTlv() NOK base" << std::endl;
#endif
/* add mandatory part */
ok &= setRawUInt32(data, tlvend, offset, image_type);
#ifdef TLV_IMG_DEBUG
if (!ok)
std::cerr << "RsTlvImage::SetTlv() NOK image" << std::endl;
#endif
ok &= binData.SetTlv(data, size, offset);
#ifdef TLV_IMG_DEBUG
if (!ok)
std::cerr << "RsTlvImage::SetTlv() NOK binData" << std::endl;
#endif
return ok;
@ -86,7 +110,10 @@ bool RsTlvImage::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialis
bool RsTlvImage::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
if (size < *offset + 4)
#ifdef TLV_IMG_DEBUG
std::cerr << "RsTlvImage::GetTlv()" << std::endl;
#endif
if (size < *offset + TLV_HEADER_SIZE)
{
return false;
}
@ -96,10 +123,20 @@ bool RsTlvImage::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialis
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend) /* check size */
{
#ifdef TLV_IMG_DEBUG
std::cerr << "RsTlvImage::GetTlv() FAIL no space" << std::endl;
#endif
return false; /* not enough space */
}
if (tlvtype != TLV_TYPE_IMAGE) /* check type */
{
#ifdef TLV_IMG_DEBUG
std::cerr << "RsTlvImage::GetTlv() FAIL wrong type" << std::endl;
#endif
return false;
}
bool ok = true;
@ -107,12 +144,33 @@ bool RsTlvImage::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialis
TlvClear();
/* skip the header */
(*offset) += 4;
(*offset) += TLV_HEADER_SIZE;
/* add mandatory parts first */
ok &= getRawUInt32(data, tlvend, offset, &(image_type));
ok &= binData.GetTlv(data, size, offset);
#ifdef TLV_IMG_DEBUG
if (!ok)
std::cerr << "RsTlvImage::GetTlv() NOK" << std::endl;
#endif
/***************************************************************************
* NB: extra components could be added (for future expansion of the type).
* or be present (if this code is reading an extended version).
*
* We must chew up the extra characters to conform with TLV specifications
***************************************************************************/
if (*offset != tlvend)
{
#ifdef TLV_DEBUG
std::cerr << "RsTlvImage::GetTlv() Warning extra bytes at end of item";
std::cerr << std::endl;
#endif
*offset = tlvend;
}
return ok;
}

View File

@ -65,9 +65,9 @@ void RsTlvSecurityKey::ShallowClear()
}
uint16_t RsTlvSecurityKey::TlvSize()
uint32_t RsTlvSecurityKey::TlvSize()
{
uint32_t s = 4; /* header + 4 for size */
uint32_t s = TLV_HEADER_SIZE; /* header + 4 for size */
/* now add comment and title length of this tlv object */
@ -84,7 +84,7 @@ uint16_t RsTlvSecurityKey::TlvSize()
bool RsTlvSecurityKey::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
/* must check sizes */
uint16_t tlvsize = TlvSize();
uint32_t tlvsize = TlvSize();
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
@ -110,11 +110,11 @@ bool RsTlvSecurityKey::SetTlv(void *data, uint32_t size, uint32_t *offset) /* s
bool RsTlvSecurityKey::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
if (size < *offset + 4)
if (size < *offset + TLV_HEADER_SIZE)
return false;
uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
uint16_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend) /* check size */
@ -129,7 +129,7 @@ bool RsTlvSecurityKey::GetTlv(void *data, uint32_t size, uint32_t *offset) /* s
TlvClear();
/* skip the header */
(*offset) += 4;
(*offset) += TLV_HEADER_SIZE;
ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_KEYID, keyId);
ok &= getRawUInt32(data, tlvend, offset, &(keyFlags));
@ -137,6 +137,22 @@ bool RsTlvSecurityKey::GetTlv(void *data, uint32_t size, uint32_t *offset) /* s
ok &= getRawUInt32(data, tlvend, offset, &(endTS));
ok &= keyData.GetTlv(data, tlvend, offset);
/***************************************************************************
* NB: extra components could be added (for future expansion of the type).
* or be present (if this code is reading an extended version).
*
* We must chew up the extra characters to conform with TLV specifications
***************************************************************************/
if (*offset != tlvend)
{
#ifdef TLV_DEBUG
std::cerr << "RsTlvSecurityKey::GetTlv() Warning extra bytes at end of item";
std::cerr << std::endl;
#endif
*offset = tlvend;
}
return ok;
}
@ -182,10 +198,10 @@ void RsTlvSecurityKeySet::TlvClear()
keys.clear(); //empty list
}
uint16_t RsTlvSecurityKeySet::TlvSize()
uint32_t RsTlvSecurityKeySet::TlvSize()
{
uint32_t s = 4; /* header + 4 for size */
uint32_t s = TLV_HEADER_SIZE; /* header */
std::map<std::string, RsTlvSecurityKey>::iterator it;
@ -205,7 +221,7 @@ uint16_t RsTlvSecurityKeySet::TlvSize()
bool RsTlvSecurityKeySet::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
/* must check sizes */
uint16_t tlvsize = TlvSize();
uint32_t tlvsize = TlvSize();
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
@ -235,11 +251,11 @@ return ok;
bool RsTlvSecurityKeySet::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
if (size < *offset + 4)
if (size < *offset + TLV_HEADER_SIZE)
return false;
uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
uint16_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend) /* check size */
@ -254,31 +270,57 @@ bool RsTlvSecurityKeySet::GetTlv(void *data, uint32_t size, uint32_t *offset) /
TlvClear();
/* skip the header */
(*offset) += 4;
(*offset) += TLV_HEADER_SIZE;
/* groupId */
ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_GROUPID, groupId);
/* while there is TLV */
while((*offset) + 2 < tlvend)
{
/* get the next type */
uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
RsTlvSecurityKey key;
ok &= key.GetTlv(data, size, offset);
if (ok)
{
keys[key.keyId] = key;
key.ShallowClear(); /* so that the Map can get control - should be ref counted*/
}
/* while there is TLV */
while((*offset) + 2 < tlvend)
{
/* get the next type */
uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
if (!ok)
{
return false;
}
switch(tlvsubtype)
{
case TLV_TYPE_SECURITYKEY:
{
RsTlvSecurityKey key;
ok &= key.GetTlv(data, size, offset);
if (ok)
{
keys[key.keyId] = key;
key.ShallowClear(); /* so that the Map can get control - should be ref counted*/
}
}
break;
default:
ok &= SkipUnknownTlv(data, tlvend, offset);
break;
}
if (!ok)
break;
}
/***************************************************************************
* NB: extra components could be added (for future expansion of the type).
* or be present (if this code is reading an extended version).
*
* We must chew up the extra characters to conform with TLV specifications
***************************************************************************/
if (*offset != tlvend)
{
#ifdef TLV_DEBUG
std::cerr << "RsTlvSecurityKeySet::GetTlv() Warning extra bytes at end of item";
std::cerr << std::endl;
#endif
*offset = tlvend;
}
return ok;
}
@ -323,9 +365,9 @@ void RsTlvKeySignature::ShallowClear()
signData.bin_len = 0;
}
uint16_t RsTlvKeySignature::TlvSize()
uint32_t RsTlvKeySignature::TlvSize()
{
uint32_t s = 4; /* header + 4 for size */
uint32_t s = TLV_HEADER_SIZE; /* header + 4 for size */
s += GetTlvStringSize(keyId);
s += signData.TlvSize();
@ -337,7 +379,7 @@ uint16_t RsTlvKeySignature::TlvSize()
bool RsTlvKeySignature::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
/* must check sizes */
uint16_t tlvsize = TlvSize();
uint32_t tlvsize = TlvSize();
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
@ -360,7 +402,7 @@ bool RsTlvKeySignature::SetTlv(void *data, uint32_t size, uint32_t *offset) /*
bool RsTlvKeySignature::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
if (size < *offset + 4)
if (size < *offset + TLV_HEADER_SIZE)
return false;
uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
@ -379,11 +421,26 @@ bool RsTlvKeySignature::GetTlv(void *data, uint32_t size, uint32_t *offset) /*
TlvClear();
/* skip the header */
(*offset) += 4;
(*offset) += TLV_HEADER_SIZE;
ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_KEYID, keyId);
ok &= signData.GetTlv(data, tlvend, offset);
/***************************************************************************
* NB: extra components could be added (for future expansion of the type).
* or be present (if this code is reading an extended version).
*
* We must chew up the extra characters to conform with TLV specifications
***************************************************************************/
if (*offset != tlvend)
{
#ifdef TLV_DEBUG
std::cerr << "RsTlvKeySignature::GetTlv() Warning extra bytes at end of item";
std::cerr << std::endl;
#endif
*offset = tlvend;
}
return ok;
}

View File

@ -48,7 +48,7 @@ class RsTlvSecurityKey: public RsTlvItem
public:
RsTlvSecurityKey();
virtual ~RsTlvSecurityKey() { return; }
virtual uint16_t TlvSize();
virtual uint32_t TlvSize();
virtual void TlvClear();
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */
@ -69,7 +69,7 @@ class RsTlvSecurityKeySet: public RsTlvItem
public:
RsTlvSecurityKeySet() { return; }
virtual ~RsTlvSecurityKeySet() { return; }
virtual uint16_t TlvSize();
virtual uint32_t TlvSize();
virtual void TlvClear();
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */
@ -85,7 +85,7 @@ class RsTlvKeySignature: public RsTlvItem
public:
RsTlvKeySignature();
virtual ~RsTlvKeySignature() { return; }
virtual uint16_t TlvSize();
virtual uint32_t TlvSize();
virtual void TlvClear();
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */

View File

@ -39,9 +39,9 @@ void RsTlvKeyValueWide::TlvClear()
wValue.clear();
}
uint16_t RsTlvKeyValueWide::TlvSize()
uint32_t RsTlvKeyValueWide::TlvSize()
{
uint32_t s = 4; /* header size */
uint32_t s = TLV_HEADER_SIZE; /* header size */
s += GetTlvWideStringSize(wKey);
s += GetTlvWideStringSize(wValue);
@ -70,7 +70,7 @@ bool RsTlvKeyValueWide::SetTlv(void *data, uint32_t size, uint32_t *offset)
{
/* must check sizes */
uint16_t tlvsize = TlvSize();
uint32_t tlvsize = TlvSize();
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
@ -94,7 +94,7 @@ bool RsTlvKeyValueWide::SetTlv(void *data, uint32_t size, uint32_t *offset)
bool RsTlvKeyValueWide::GetTlv(void *data, uint32_t size, uint32_t *offset)
{
if (size < *offset + 4)
if (size < *offset + TLV_HEADER_SIZE)
return false;
uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
@ -113,7 +113,7 @@ bool RsTlvKeyValueWide::GetTlv(void *data, uint32_t size, uint32_t *offset)
TlvClear();
/* skip the header */
(*offset) += 4;
(*offset) += TLV_HEADER_SIZE;
/* while there is TLV */
while((*offset) + 2 < tlvend)
@ -130,16 +130,32 @@ bool RsTlvKeyValueWide::GetTlv(void *data, uint32_t size, uint32_t *offset)
ok &= GetTlvWideString(data, tlvend, offset, TLV_TYPE_WSTR_VALUE, wValue);
break;
default:
ok &= SkipUnknownTlv(data, tlvend, offset);
break;
}
if (!ok)
{
return false;
break;
}
}
/***************************************************************************
* NB: extra components could be added (for future expansion of the type).
* or be present (if this code is reading an extended version).
*
* We must chew up the extra characters to conform with TLV specifications
***************************************************************************/
if (*offset != tlvend)
{
#ifdef TLV_DEBUG
std::cerr << "RsTlvKeyValueWide::GetTlv() Warning extra bytes at end of item";
std::cerr << std::endl;
#endif
*offset = tlvend;
}
return ok;
}
@ -151,9 +167,9 @@ void RsTlvKeyValueWideSet::TlvClear()
wPairs.clear();
}
uint16_t RsTlvKeyValueWideSet::TlvSize()
uint32_t RsTlvKeyValueWideSet::TlvSize()
{
uint32_t s = 4; /* header size */
uint32_t s = TLV_HEADER_SIZE; /* header size */
std::list<RsTlvKeyValueWide>::iterator it;
@ -185,7 +201,7 @@ bool RsTlvKeyValueWideSet::SetTlv(void *data, uint32_t size, uint32_t* offset)
{
/* must check sizes */
uint16_t tlvsize = TlvSize();
uint32_t tlvsize = TlvSize();
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
@ -207,7 +223,7 @@ bool RsTlvKeyValueWideSet::SetTlv(void *data, uint32_t size, uint32_t* offset)
bool RsTlvKeyValueWideSet::GetTlv(void *data, uint32_t size, uint32_t* offset)
{
if (size < *offset + 4)
if (size < *offset + TLV_HEADER_SIZE)
return false;
uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
@ -226,23 +242,51 @@ bool RsTlvKeyValueWideSet::GetTlv(void *data, uint32_t size, uint32_t* offset)
TlvClear();
/* skip the header */
(*offset) += 4;
(*offset) += TLV_HEADER_SIZE;
/* while there is TLV */
while((*offset) + 2 < tlvend)
{
/* while there is TLV */
while((*offset) + 2 < tlvend)
{
/* get the next type */
uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
RsTlvKeyValueWide wPair;
ok &= wPair.GetTlv(data, size, offset);
wPairs.push_back(wPair);
switch(tlvsubtype)
{
case TLV_TYPE_WKEYVALUE:
{
RsTlvKeyValueWide kv;
ok &= kv.GetTlv(data, size, offset);
if (ok)
{
wPairs.push_back(kv);
}
}
break;
default:
ok &= SkipUnknownTlv(data, tlvend, offset);
break;
if (!ok)
{
return false;
}
}
if (!ok)
break;
}
/***************************************************************************
* NB: extra components could be added (for future expansion of the type).
* or be present (if this code is reading an extended version).
*
* We must chew up the extra characters to conform with TLV specifications
***************************************************************************/
if (*offset != tlvend)
{
#ifdef TLV_DEBUG
std::cerr << "RsTlvBinaryData::GetTlv() Warning extra bytes at end of item";
std::cerr << std::endl;
#endif
*offset = tlvend;
}
return ok;
}

View File

@ -35,7 +35,7 @@ class RsTlvKeyValueWide: public RsTlvItem
RsTlvKeyValueWide() { return;}
virtual ~RsTlvKeyValueWide() { return;}
virtual uint16_t TlvSize();
virtual uint32_t TlvSize();
virtual void TlvClear();
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset);
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */
@ -53,7 +53,7 @@ class RsTlvKeyValueWideSet : public RsTlvItem
RsTlvKeyValueWideSet() { return;}
virtual ~RsTlvKeyValueWideSet() { return; }
virtual uint16_t TlvSize();
virtual uint32_t TlvSize();
virtual void TlvClear();
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset);
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */

View File

@ -81,7 +81,7 @@ RsTlvBinaryData::~RsTlvBinaryData()
/// used to allocate memory andinitialize binary data member
bool RsTlvBinaryData::setBinData(void *data, uint16_t size)
bool RsTlvBinaryData::setBinData(void *data, uint32_t size)
{
/* ready to load */
TlvClear();
@ -115,9 +115,9 @@ void RsTlvBinaryData::TlvShallowClear()
bin_len = 0;
}
uint16_t RsTlvBinaryData::TlvSize()
uint32_t RsTlvBinaryData::TlvSize()
{
uint32_t s = 4; /* header */
uint32_t s = TLV_HEADER_SIZE; /* header */
if (bin_data != NULL)
s += bin_len; // len is the size of data
@ -129,7 +129,7 @@ uint16_t RsTlvBinaryData::TlvSize()
bool RsTlvBinaryData::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
/* must check sizes */
uint16_t tlvsize = TlvSize();
uint32_t tlvsize = TlvSize();
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
@ -150,7 +150,6 @@ bool RsTlvBinaryData::SetTlv(void *data, uint32_t size, uint32_t *offset) /*
memcpy(&(((uint8_t *) data)[*offset]), bin_data, bin_len);
*offset += bin_len;
}
return ok;
}
@ -158,19 +157,19 @@ bool RsTlvBinaryData::SetTlv(void *data, uint32_t size, uint32_t *offset) /*
bool RsTlvBinaryData::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
if (size < *offset + 4)
if (size < *offset + TLV_HEADER_SIZE)
{
return false; /* not enough space to get the header */
}
uint16_t tlvtype_in = GetTlvType( &(((uint8_t *) data)[*offset]) );
uint16_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend) /* check size */
return false; /* not enough space */
if (tlvsize < 4)
if (tlvsize < TLV_HEADER_SIZE)
{
return false; /* bad tlv size */
}
@ -179,11 +178,26 @@ bool RsTlvBinaryData::GetTlv(void *data, uint32_t size, uint32_t *offset) /*
return false;
/* skip the header */
(*offset) += 4;
(*offset) += TLV_HEADER_SIZE;
bool ok = setBinData(&(((uint8_t *) data)[*offset]), tlvsize - 4);
bool ok = setBinData(&(((uint8_t *) data)[*offset]), tlvsize - TLV_HEADER_SIZE);
(*offset) += bin_len;
/***************************************************************************
* NB: extra components could be added (for future expansion of the type).
* or be present (if this code is reading an extended version).
*
* We must chew up the extra characters to conform with TLV specifications
***************************************************************************/
if (*offset != tlvend)
{
#ifdef TLV_DEBUG
std::cerr << "RsTlvBinaryData::GetTlv() Warning extra bytes at end of item";
std::cerr << std::endl;
#endif
*offset = tlvend;
}
return ok;
}
@ -216,16 +230,24 @@ std::ostream &RsTlvBinaryData::print(std::ostream &out, uint16_t indent)
/************************************* Peer Id Set ************************************/
void RsTlvPeerIdSet::TlvClear()
RsTlvPeerIdSet::RsTlvPeerIdSet(): RsTlvStringSet(TLV_TYPE_PEERSET) {}
RsTlvHashSet::RsTlvHashSet(): RsTlvStringSet(TLV_TYPE_HASHSET) {}
RsTlvStringSet::RsTlvStringSet(uint16_t type) :mType(type)
{
}
void RsTlvStringSet::TlvClear()
{
ids.clear();
}
uint16_t RsTlvPeerIdSet::TlvSize()
uint32_t RsTlvStringSet::TlvSize()
{
uint32_t s = 4; /* header */
uint32_t s = TLV_HEADER_SIZE; /* header */
/* determine the total size of ids strings in list */
@ -241,10 +263,10 @@ uint16_t RsTlvPeerIdSet::TlvSize()
}
bool RsTlvPeerIdSet::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
bool RsTlvStringSet::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
/* must check sizes */
uint16_t tlvsize = TlvSize();
uint32_t tlvsize = TlvSize();
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
@ -254,7 +276,7 @@ bool RsTlvPeerIdSet::SetTlv(void *data, uint32_t size, uint32_t *offset) /*
/* start at data[offset] */
ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_PEERSET , tlvsize);
ok &= SetTlvBase(data, tlvend, offset, mType , tlvsize);
/* determine the total size of ids strings in list */
@ -263,7 +285,7 @@ bool RsTlvPeerIdSet::SetTlv(void *data, uint32_t size, uint32_t *offset) /*
for(it = ids.begin(); it != ids.end() ; ++it)
{
if (it->length() > 0)
ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_PEERID, *it);
ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_GENID, *it);
}
return ok;
@ -271,13 +293,13 @@ bool RsTlvPeerIdSet::SetTlv(void *data, uint32_t size, uint32_t *offset) /*
}
bool RsTlvPeerIdSet::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
bool RsTlvStringSet::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
if (size < *offset + 4)
if (size < *offset + TLV_HEADER_SIZE)
return false;
uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
uint16_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
uint32_t tlvend = *offset + tlvsize;
@ -285,7 +307,7 @@ bool RsTlvPeerIdSet::GetTlv(void *data, uint32_t size, uint32_t *offset) /*
if (size < tlvend) /* check size */
return false; /* not enough space */
if (tlvtype != TLV_TYPE_PEERSET) /* check type */
if (tlvtype != mType) /* check type */
return false;
bool ok = true;
@ -294,7 +316,7 @@ bool RsTlvPeerIdSet::GetTlv(void *data, uint32_t size, uint32_t *offset) /*
TlvClear();
/* skip the header */
(*offset) += 4;
(*offset) += TLV_HEADER_SIZE;
@ -304,32 +326,56 @@ bool RsTlvPeerIdSet::GetTlv(void *data, uint32_t size, uint32_t *offset) /*
/* get the next type */
uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
if (tlvsubtype == TLV_TYPE_STR_PEERID)
if (tlvsubtype == TLV_TYPE_STR_GENID)
{
std::string newIds;
ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_PEERID, newIds);
ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_GENID, newIds);
if(ok)
{
ids.push_back(newIds);
}
}
else
{
/* Step past unknown TLV TYPE */
ok &= SkipUnknownTlv(data, tlvend, offset);
}
if (!ok)
{
return false;
break;
}
}
/***************************************************************************
* NB: extra components could be added (for future expansion of the type).
* or be present (if this code is reading an extended version).
*
* We must chew up the extra characters to conform with TLV specifications
***************************************************************************/
if (*offset != tlvend)
{
#ifdef TLV_DEBUG
std::cerr << "RsTlvPeerIdSet::GetTlv() Warning extra bytes at end of item";
std::cerr << std::endl;
#endif
*offset = tlvend;
}
return ok;
}
/// print to screen RsTlvPeerIdSet contents
std::ostream &RsTlvPeerIdSet::print(std::ostream &out, uint16_t indent)
/// print to screen RsTlvStringSet contents
std::ostream &RsTlvStringSet::print(std::ostream &out, uint16_t indent)
{
printBase(out, "RsTlvPeerIdSet", indent);
printBase(out, "RsTlvStringSet", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "type:" << mType;
out << std::endl;
std::list<std::string>::iterator it;
for(it = ids.begin(); it != ids.end() ; ++it)
{
@ -338,17 +384,21 @@ std::ostream &RsTlvPeerIdSet::print(std::ostream &out, uint16_t indent)
out << std::endl;
}
printEnd(out, "RsTlvPeerIdSet", indent);
printEnd(out, "RsTlvStringSet", indent);
return out;
}
/// print to screen RsTlvPeerIdSet contents
std::ostream &RsTlvPeerIdSet::printHex(std::ostream &out, uint16_t indent)
/// print to screen RsTlvStringSet contents
std::ostream &RsTlvStringSet::printHex(std::ostream &out, uint16_t indent)
{
printBase(out, "RsTlvPeerIdSet", indent);
printBase(out, "RsTlvStringSet", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "type:" << mType;
out << std::endl;
std::list<std::string>::iterator it;
for(it = ids.begin(); it != ids.end() ; ++it)
{
@ -357,7 +407,7 @@ std::ostream &RsTlvPeerIdSet::printHex(std::ostream &out, uint16_t indent)
out << std::endl;
}
printEnd(out, "RsTlvPeerIdSet", indent);
printEnd(out, "RsTlvStringSet", indent);
return out;
}
@ -371,9 +421,9 @@ void RsTlvServiceIdSet::TlvClear()
}
uint16_t RsTlvServiceIdSet::TlvSize()
uint32_t RsTlvServiceIdSet::TlvSize()
{
uint32_t s = 4; /* header */
uint32_t s = TLV_HEADER_SIZE; /* header */
/* determine the total size of ids strings in list */
std::list<uint32_t>::iterator it;
@ -389,7 +439,7 @@ uint16_t RsTlvServiceIdSet::TlvSize()
bool RsTlvServiceIdSet::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
/* must check sizes */
uint16_t tlvsize = TlvSize();
uint32_t tlvsize = TlvSize();
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
@ -415,11 +465,11 @@ bool RsTlvServiceIdSet::SetTlv(void *data, uint32_t size, uint32_t *offset)
bool RsTlvServiceIdSet::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
if (size < *offset + 4)
if (size < *offset + TLV_HEADER_SIZE)
return false;
uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
uint16_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend) /* check size */
@ -434,7 +484,7 @@ bool RsTlvServiceIdSet::GetTlv(void *data, uint32_t size, uint32_t *offset)
TlvClear();
/* skip the header */
(*offset) += 4;
(*offset) += TLV_HEADER_SIZE;
/* while there is TLV */
while((*offset) + 2 < tlvend)
@ -452,12 +502,33 @@ bool RsTlvServiceIdSet::GetTlv(void *data, uint32_t size, uint32_t *offset)
}
}
else
{
/* Step past unknown TLV TYPE */
ok &= SkipUnknownTlv(data, tlvend, offset);
}
if (!ok)
{
return false;
break;
}
}
/***************************************************************************
* NB: extra components could be added (for future expansion of the type).
* or be present (if this code is reading an extended version).
*
* We must chew up the extra characters to conform with TLV specifications
***************************************************************************/
if (*offset != tlvend)
{
#ifdef TLV_DEBUG
std::cerr << "RsTlvServiceIdSet::GetTlv() Warning extra bytes at end of item";
std::cerr << std::endl;
#endif
*offset = tlvend;
}
return ok;
}
@ -489,9 +560,9 @@ void RsTlvKeyValue::TlvClear()
value = "";
}
uint16_t RsTlvKeyValue::TlvSize()
uint32_t RsTlvKeyValue::TlvSize()
{
uint32_t s = 4; /* header + 4 for size */
uint32_t s = TLV_HEADER_SIZE; /* header */
/* now add comment and title length of this tlv object */
@ -507,7 +578,7 @@ uint16_t RsTlvKeyValue::TlvSize()
bool RsTlvKeyValue::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
/* must check sizes */
uint16_t tlvsize = TlvSize();
uint32_t tlvsize = TlvSize();
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
@ -532,11 +603,11 @@ return ok;
bool RsTlvKeyValue::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
if (size < *offset + 4)
if (size < *offset + TLV_HEADER_SIZE)
return false;
uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
uint16_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend) /* check size */
@ -551,7 +622,7 @@ bool RsTlvKeyValue::GetTlv(void *data, uint32_t size, uint32_t *offset) /* seri
TlvClear();
/* skip the header */
(*offset) += 4;
(*offset) += TLV_HEADER_SIZE;
/* while there is TLV */
while((*offset) + 2 < tlvend)
@ -568,16 +639,33 @@ bool RsTlvKeyValue::GetTlv(void *data, uint32_t size, uint32_t *offset) /* seri
ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_VALUE, value);
break;
default:
ok &= SkipUnknownTlv(data, tlvend, offset);
break;
}
if (!ok)
{
return false;
break;
}
}
/***************************************************************************
* NB: extra components could be added (for future expansion of the type).
* or be present (if this code is reading an extended version).
*
* We must chew up the extra characters to conform with TLV specifications
***************************************************************************/
if (*offset != tlvend)
{
#ifdef TLV_DEBUG
std::cerr << "RsTlvKeyValue::GetTlv() Warning extra bytes at end of item";
std::cerr << std::endl;
#endif
*offset = tlvend;
}
return ok;
}
@ -605,10 +693,10 @@ void RsTlvKeyValueSet::TlvClear()
pairs.clear(); //empty list
}
uint16_t RsTlvKeyValueSet::TlvSize()
uint32_t RsTlvKeyValueSet::TlvSize()
{
uint32_t s = 4; /* header + 4 for size */
uint32_t s = TLV_HEADER_SIZE; /* header */
std::list<RsTlvKeyValue>::iterator it;
@ -626,7 +714,7 @@ uint16_t RsTlvKeyValueSet::TlvSize()
bool RsTlvKeyValueSet::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
/* must check sizes */
uint16_t tlvsize = TlvSize();
uint32_t tlvsize = TlvSize();
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
@ -654,11 +742,11 @@ return ok;
bool RsTlvKeyValueSet::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
if (size < *offset + 4)
if (size < *offset + TLV_HEADER_SIZE)
return false;
uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
uint16_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend) /* check size */
@ -673,27 +761,51 @@ bool RsTlvKeyValueSet::GetTlv(void *data, uint32_t size, uint32_t *offset) /* s
TlvClear();
/* skip the header */
(*offset) += 4;
(*offset) += TLV_HEADER_SIZE;
/* while there is TLV */
while((*offset) + 2 < tlvend)
{
/* get the next type */
uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
RsTlvKeyValue kv;
ok &= kv.GetTlv(data, size, offset);
if (ok)
{
pairs.push_back(kv);
}
/* while there is TLV */
while((*offset) + 2 < tlvend)
{
/* get the next type */
uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
if (!ok)
{
return false;
}
switch(tlvsubtype)
{
case TLV_TYPE_KEYVALUE:
{
RsTlvKeyValue kv;
ok &= kv.GetTlv(data, size, offset);
if (ok)
{
pairs.push_back(kv);
}
}
break;
default:
ok &= SkipUnknownTlv(data, tlvend, offset);
break;
}
if (!ok)
break;
}
/***************************************************************************
* NB: extra components could be added (for future expansion of the type).
* or be present (if this code is reading an extended version).
*
* We must chew up the extra characters to conform with TLV specifications
***************************************************************************/
if (*offset != tlvend)
{
#ifdef TLV_DEBUG
std::cerr << "RsTlvKeyValueSet::GetTlv() Warning extra bytes at end of item";
std::cerr << std::endl;
#endif
*offset = tlvend;
}
return ok;
}

View File

@ -36,7 +36,6 @@
#include <stdlib.h>
#include <stdint.h>
//#define RS_TLV_TYPE_FILE_ITEM 0x0000
//! A base class for all tlv items
/*! This class is provided to allow the serialisation and deserialization of compund
@ -47,7 +46,7 @@ class RsTlvItem
public:
RsTlvItem() { return; }
virtual ~RsTlvItem() { return; }
virtual uint16_t TlvSize() = 0;
virtual uint32_t TlvSize() = 0;
virtual void TlvClear() = 0;
virtual void TlvShallowClear(); /*! Don't delete allocated data */
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) = 0; /* serialise */
@ -67,42 +66,103 @@ class RsTlvBinaryData: public RsTlvItem
public:
RsTlvBinaryData(uint16_t t);
virtual ~RsTlvBinaryData();
virtual uint16_t TlvSize();
virtual uint32_t TlvSize();
virtual void TlvClear(); /*! Initialize fields to empty legal values ( "0", "", etc) */
virtual void TlvShallowClear(); /*! Don't delete the binary data */
/// Serialise.
/*! Serialise Tlv to buffer(*data) of 'size' bytes starting at *offset */
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset);
/// Deserialise.
/*! Deserialise Tlv buffer(*data) of 'size' bytes starting at *offset */
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset);
virtual std::ostream &print(std::ostream &out, uint16_t indent); /*! Error/Debug util function */
bool setBinData(void *data, uint16_t size);
bool setBinData(void *data, uint32_t size);
uint16_t tlvtype; /// set/checked against TLV input
uint16_t bin_len; /// size of malloc'ed data (not serialised)
uint32_t bin_len; /// size of malloc'ed data (not serialised)
void *bin_data; /// mandatory
};
/**** MORE TLV *****
*
*
*/
class RsTlvStringSet: public RsTlvItem
{
public:
RsTlvStringSet(uint16_t type);
virtual ~RsTlvStringSet() { return; }
virtual uint32_t TlvSize();
virtual void TlvClear();
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */
virtual std::ostream &print(std::ostream &out, uint16_t indent);
virtual std::ostream &printHex(std::ostream &out, uint16_t indent); /* SPECIAL One */
uint16_t mType;
std::list<std::string> ids; /* Mandatory */
};
class RsTlvPeerIdSet: public RsTlvStringSet
{
public:
RsTlvPeerIdSet();
};
class RsTlvHashSet: public RsTlvStringSet
{
public:
RsTlvHashSet();
};
class RsTlvServiceIdSet: public RsTlvItem
{
public:
RsTlvServiceIdSet() { return; }
virtual ~RsTlvServiceIdSet() { return; }
virtual uint32_t TlvSize();
virtual void TlvClear();
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */
virtual std::ostream &print(std::ostream &out, uint16_t indent);
std::list<uint32_t> ids; /* Mandatory */
};
/**** MORE TLV *****
*
* File Items/Data.
*
*/
class RsTlvFileItem: public RsTlvItem
{
public:
RsTlvFileItem();
virtual ~RsTlvFileItem() { return; }
virtual uint16_t TlvSize();
virtual uint32_t TlvSize();
virtual void TlvClear();
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */
virtual std::ostream &print(std::ostream &out, uint16_t indent);
uint64_t filesize; /// Mandatory: size of file to be downloaded
uint64_t filesize; /// Mandatory: size of file to be downloaded
std::string hash; /// Mandatory: to find file
std::string name; /// Optional: name of file
std::string path; /// Optional: path on host computer
uint32_t pop; /// Optional: Popularity of file
uint32_t age; /// Optional: age of file
// For chunk hashing.
uint32_t piecesize; /// Optional: bytes/piece for hashset.
RsTlvHashSet hashset; /// Optional: chunk hashes.
};
class RsTlvFileSet: public RsTlvItem
@ -110,7 +170,7 @@ class RsTlvFileSet: public RsTlvItem
public:
RsTlvFileSet() { return; }
virtual ~RsTlvFileSet() { return; }
virtual uint16_t TlvSize();
virtual uint32_t TlvSize();
virtual void TlvClear();
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */
@ -127,7 +187,7 @@ class RsTlvFileData: public RsTlvItem
public:
RsTlvFileData();
virtual ~RsTlvFileData() { return; }
virtual uint16_t TlvSize();
virtual uint32_t TlvSize();
virtual void TlvClear();
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */
@ -139,43 +199,6 @@ virtual std::ostream &print(std::ostream &out, uint16_t indent);
};
/**** MORE TLV *****
*
*
*/
class RsTlvPeerIdSet: public RsTlvItem
{
public:
RsTlvPeerIdSet() { return; }
virtual ~RsTlvPeerIdSet() { return; }
virtual uint16_t TlvSize();
virtual void TlvClear();
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */
virtual std::ostream &print(std::ostream &out, uint16_t indent);
virtual std::ostream &printHex(std::ostream &out, uint16_t indent); /* SPECIAL One */
std::list<std::string> ids; /* Mandatory */
};
class RsTlvServiceIdSet: public RsTlvItem
{
public:
RsTlvServiceIdSet() { return; }
virtual ~RsTlvServiceIdSet() { return; }
virtual uint16_t TlvSize();
virtual void TlvClear();
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */
virtual std::ostream &print(std::ostream &out, uint16_t indent);
std::list<uint32_t> ids; /* Mandatory */
};
/**** MORE TLV *****
@ -189,7 +212,7 @@ class RsTlvKeyValue: public RsTlvItem
public:
RsTlvKeyValue() { return; }
virtual ~RsTlvKeyValue() { return; }
virtual uint16_t TlvSize();
virtual uint32_t TlvSize();
virtual void TlvClear();
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */
@ -204,7 +227,7 @@ class RsTlvKeyValueSet: public RsTlvItem
public:
RsTlvKeyValueSet() { return; }
virtual ~RsTlvKeyValueSet() { return; }
virtual uint16_t TlvSize();
virtual uint32_t TlvSize();
virtual void TlvClear();
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */
@ -219,7 +242,7 @@ class RsTlvImage: public RsTlvItem
public:
RsTlvImage();
virtual ~RsTlvImage() { return; }
virtual uint16_t TlvSize();
virtual uint32_t TlvSize();
virtual void TlvClear();
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */

View File

@ -0,0 +1,194 @@
/*
* libretroshare/src/serialiser: tlvrandom_test.cc
*
* RetroShare Serialiser.
*
* Copyright 2009 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
/******************************************************************
* tlvrandom_test.
*
* This test is designed to attempt to break the TLV serialiser.
*
* To do this we throw random data at the serialisers and try to decode it.
* As the serialiser will only attempt to deserialise if the tlvtype matches
* we cheat a little, and make this match - to increase to actual deserialise
* attempts.
*
* This test runs for 30 seconds and attempts to do as
* many deserialisation as possible.
*/
#include <string.h>
#include <iostream>
#include "serialiser/rstlvbase.h"
#include "serialiser/rstlvtypes.h"
#include "serialiser/rstlvkeys.h"
#include "serialiser/rstlvkvwide.h"
#include "serialiser/rstlvutil.h"
#include "util/utest.h"
INITTEST();
#define TEST_LENGTH 30
static int test_TlvRandom(void *data, uint32_t len, uint32_t offset);
int main()
{
std::cerr << "TlvRandom Tests" << std::endl;
/* random data array to work through */
uint32_t dsize = 10000000;
uint32_t i;
uint8_t *data = (uint8_t *) malloc(dsize);
if (!data)
{
std::cerr << "Failed to allocate array";
std::cerr << std::endl;
exit(1);
}
time_t startTs = time(NULL);
time_t endTs = startTs + TEST_LENGTH;
srandom(startTs);
for(i = 0; i < dsize; i++)
{
data[i] = random() % 256;
}
std::cerr << "TlvRandom Tests: setup data." << std::endl;
int count = 0;
for(i = 0; endTs > time(NULL); i += 2)
{
uint32_t len = dsize - i;
count += test_TlvRandom(&(data[i]), len, i);
std::cerr << "Run: " << count << " tests";
std::cerr << std::endl;
}
FINALREPORT("RsTlvItems Tests");
return TESTRESULT();
}
#define BIN_LEN 523456 /* bigger than 64k */
int test_TlvItem(RsTlvItem *item, void *data, uint32_t size, uint32_t offset);
int test_SetTlvItem(RsTlvItem *item, uint16_t type, void *data, uint32_t size, uint32_t offset);
int test_TlvRandom(void *data, uint32_t len, uint32_t offset)
{
uint32_t tmpoffset = 0;
/* List of all the TLV types it could be! */
RsTlvSecurityKey skey;
RsTlvSecurityKeySet skeyset;
RsTlvKeySignature keysign;
RsTlvBinaryData bindata(TLV_TYPE_IMAGE);
RsTlvFileItem fileitem;
RsTlvFileSet fileset;
RsTlvFileData filedata;
RsTlvPeerIdSet peerset;
RsTlvServiceIdSet servset;
RsTlvKeyValue kv;
RsTlvKeyValueSet kvset;
RsTlvKeyValueWide kvwide;
RsTlvKeyValueWideSet kvwideset;
RsTlvImage image;
/* try to decode - with all types first */
std::cerr << "test_TlvRandom:: Testing Files " << std::endl;
test_TlvItem(&bindata, data, len, offset);
test_TlvItem(&fileitem, data, len, offset);
test_TlvItem(&fileset, data, len, offset);
test_TlvItem(&filedata, data, len, offset);
std::cerr << "test_TlvRandom:: Testing Sets " << std::endl;
test_TlvItem(&peerset, data, len, offset);
test_TlvItem(&servset, data, len, offset);
test_TlvItem(&kv, data, len, offset);
test_TlvItem(&kvset, data, len, offset);
test_TlvItem(&kvwide, data, len, offset);
test_TlvItem(&kvwideset, data, len, offset);
std::cerr << "test_TlvRandom:: Testing Keys " << std::endl;
test_TlvItem(&skey, data, len, offset);
test_TlvItem(&skeyset, data, len, offset);
test_TlvItem(&keysign, data, len, offset);
/* now set the type correctly before decoding */
std::cerr << "test_TlvRandom:: Testing Files (TYPESET)" << std::endl;
test_SetTlvItem(&bindata, TLV_TYPE_IMAGE, data, len, offset);
test_SetTlvItem(&fileitem,TLV_TYPE_FILEITEM, data, len, offset);
test_SetTlvItem(&fileset, TLV_TYPE_FILESET, data, len, offset);
test_SetTlvItem(&filedata, TLV_TYPE_FILEDATA, data, len, offset);
std::cerr << "test_TlvRandom:: Testing Sets (TYPESET)" << std::endl;
test_SetTlvItem(&peerset, TLV_TYPE_PEERSET, data, len, offset);
test_SetTlvItem(&servset, TLV_TYPE_SERVICESET, data, len, offset);
test_SetTlvItem(&kv, TLV_TYPE_KEYVALUE, data, len, offset);
test_SetTlvItem(&kvset, TLV_TYPE_KEYVALUESET, data, len, offset);
test_SetTlvItem(&kvwide, TLV_TYPE_WKEYVALUE, data, len, offset);
test_SetTlvItem(&kvwideset, TLV_TYPE_WKEYVALUESET, data, len, offset);
std::cerr << "test_TlvRandom:: Testing Keys (TYPESET)" << std::endl;
test_SetTlvItem(&skey, TLV_TYPE_SECURITYKEY, data, len, offset);
test_SetTlvItem(&skeyset, TLV_TYPE_SECURITYKEYSET, data, len, offset);
test_SetTlvItem(&keysign, TLV_TYPE_KEYSIGNATURE, data, len, offset);
return 26; /* number of tests */
}
int test_TlvItem(RsTlvItem *item, void *data, uint32_t size, uint32_t offset)
{
uint32_t tmp_offset = offset;
if (item->GetTlv(data, size, &tmp_offset))
{
std::cerr << "TLV decoded Random!";
std::cerr << std::endl;
item->print(std::cerr, 20);
}
else
{
std::cerr << "TLV failed to decode";
std::cerr << std::endl;
}
}
int test_SetTlvItem(RsTlvItem *item, uint16_t type, void *data, uint32_t size, uint32_t offset)
{
/* set TLV type first! */
void *typedata = (((uint8_t *) data) + offset);
SetTlvType(typedata, size - offset, type);
return test_TlvItem(item, data, size, offset);
}

View File

@ -426,4 +426,408 @@ bool RsDirUtil::renameFile(const std::string& from, const std::string& to)
return true ;
}
/************************* WIDE STRING ***************************/
/************************* WIDE STRING ***************************/
/************************* WIDE STRING ***************************/
std::wstring RsDirUtil::getWideTopDir(std::wstring dir)
{
std::wstring top;
/* find the subdir: [/][dir1.../]<top>[/]
*/
int i,j;
int len = dir.length();
for(j = len - 1; (j > 0) && (dir[j] == '/'); j--);
for(i = j; (i > 0) && (dir[i] != '/'); i--);
if (dir[i] == '/')
i++;
for(; i <= j; i++)
{
top += dir[i];
}
return top;
}
std::wstring RsDirUtil::removeWideTopDir(std::wstring dir)
{
std::wstring rest;
/* remove the subdir: [/][dir1.../]<top>[/]
*/
int i,j;
int len = dir.length();
for(j = len - 1; (j > 0) && (dir[j] == '/'); j--);
for(i = j; (i >= 0) && (dir[i] != '/'); i--);
/* remove any more slashes */
for(; (i >= 0) && (dir[i] == '/'); i--);
for(j = 0; j <= i; j++)
{
rest += dir[j];
}
return rest;
}
std::wstring RsDirUtil::getWideRootDir(std::wstring dir)
{
std::wstring root;
/* find the subdir: [/]root[/...]
*/
int i,j;
int len = dir.length();
for(i = 0; (i < len) && (dir[i] == '/'); i++);
for(j = i; (j < len) && (dir[j] != '/'); j++);
if (i == j)
return root; /* empty */
for(; i < j; i++)
{
root += dir[i];
}
return root;
}
std::wstring RsDirUtil::removeWideRootDir(std::wstring path)
{
unsigned int i, j;
unsigned int len = path.length();
std::wstring output;
/* chew leading '/'s */
for(i = 0; (i < len) && (path[i] == '/'); i++);
if (i == len)
return output; /* empty string */
for(j = i; (j < len) && (path[j] != '/'); j++); /* run to next '/' */
for(; (j < len) && (path[j] == '/'); j++); /* chew leading '/'s */
for(; j < len; j++)
{
output += path[j];
}
return output;
}
std::wstring RsDirUtil::removeWideRootDirs(std::wstring path, std::wstring root)
{
/* too tired */
std::wstring notroot;
unsigned int i = 0, j = 0;
/* catch empty data */
if ((root.length() < 1) || (path.length() < 1))
return notroot;
if ((path[0] == '/') && (root[0] != '/'))
{
i++;
}
for(; (i < path.length()) && (j < root.length()) && (path[i] == root[j]); i++, j++);
/* should have consumed root. */
if (j == root.length())
{
//std::cerr << "matched root!" << std::endl;
}
else
{
//std::cerr << "failed i: " << i << ", j: " << j << std::endl;
//std::cerr << "root: " << root << " path: " << path << std::endl;
return notroot;
}
if (path[i] == '/')
{
i++;
}
for(; i < path.length(); i++)
{
notroot += path[i];
}
//std::cerr << "Found NotRoot: " << notroot << std::endl;
return notroot;
}
int RsDirUtil::breakupWideDirList(std::wstring path,
std::list<std::wstring> &subdirs)
{
int start = 0;
unsigned int i;
for(i = 0; i < path.length(); i++)
{
if (path[i] == '/')
{
if (i - start > 0)
{
subdirs.push_back(path.substr(start, i-start));
}
start = i+1;
}
}
// get the final one.
if (i - start > 0)
{
subdirs.push_back(path.substr(start, i-start));
}
return 1;
}
bool RsDirUtil::checkWideDirectory(std::wstring dir)
{
struct stat buf;
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
std::string d(dir.begin(), dir.end());
int val = stat(d.c_str(), &buf);
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
if (val == -1)
{
#ifdef RSDIR_DEBUG
std::cerr << "RsDirUtil::checkDirectory() ";
std::cerr << d << " doesn't exist" << std::endl;
#endif
return false;
}
else if (!S_ISDIR(buf.st_mode))
{
// Some other type - error.
#ifdef RSDIR_DEBUG
std::cerr << "RsDirUtil::checkDirectory() ";
std::cerr << d << " is not Directory" << std::endl;
#endif
return false;
}
return true;
}
bool RsDirUtil::checkWideCreateDirectory(std::wstring dir)
{
struct stat buf;
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
std::string d(dir.begin(), dir.end());
int val = stat(d.c_str(), &buf);
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
if (val == -1)
{
// directory don't exist. create.
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS // UNIX
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
if (-1 == mkdir(d.c_str(), 0777))
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
#else // WIN
if (-1 == mkdir(d.c_str()))
#endif
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
{
#ifdef RSDIR_DEBUG
std::cerr << "check_create_directory() Fatal Error --";
std::cerr <<std::endl<< "\tcannot create:" <<d<<std::endl;
#endif
return 0;
}
#ifdef RSDIR_DEBUG
std::cerr << "check_create_directory()";
std::cerr <<std::endl<< "\tcreated:" <<d<<std::endl;
#endif
}
else if (!S_ISDIR(buf.st_mode))
{
// Some other type - error.
#ifdef RSDIR_DEBUG
std::cerr<<"check_create_directory() Fatal Error --";
std::cerr<<std::endl<<"\t"<<d<<" is nor Directory"<<std::endl;
#endif
return 0;
}
#ifdef RSDIR_DEBUG
std::cerr << "check_create_directory()";
std::cerr <<std::endl<< "\tDir Exists:" <<d<<std::endl;
#endif
return 1;
}
#include <dirent.h>
bool RsDirUtil::cleanupWideDirectory(std::wstring cleandir, std::list<std::wstring> keepFiles)
{
/* check for the dir existance */
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
std::string cd(cleandir.begin(), cleandir.end());
DIR *dir = opendir(cd.c_str());
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
std::list<std::wstring>::const_iterator it;
if (!dir)
{
return false;
}
struct dirent *dent;
struct stat buf;
while(NULL != (dent = readdir(dir)))
{
/* check entry type */
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
std::string fname(dent -> d_name);
std::wstring wfname(fname.begin(), fname.end());
std::string fullname = cd + "/" + fname;
if (-1 != stat(fullname.c_str(), &buf))
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
{
/* only worry about files */
if (S_ISREG(buf.st_mode))
{
/* check if we should keep it */
if (keepFiles.end() == (it = std::find(keepFiles.begin(), keepFiles.end(), wfname)))
{
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
/* can remove */
remove(fullname.c_str());
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
}
}
}
}
/* close directory */
closedir(dir);
return true;
}
/* slightly nicer helper function */
bool RsDirUtil::hashWideFile(std::wstring filepath,
std::wstring &name, std::string &hash, uint64_t &size)
{
if (getWideFileHash(filepath, hash, size))
{
/* extract file name */
name = RsDirUtil::getWideTopDir(filepath);
return true;
}
return false;
}
#include <openssl/sha.h>
#include <sstream>
#include <iomanip>
/* Function to hash, and get details of a file */
bool RsDirUtil::getWideFileHash(std::wstring filepath,
std::string &hash, uint64_t &size)
{
FILE *fd;
int len;
SHA_CTX *sha_ctx = new SHA_CTX;
unsigned char sha_buf[SHA_DIGEST_LENGTH];
unsigned char gblBuf[512];
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
std::string fp(filepath.begin(), filepath.end());
if (NULL == (fd = fopen(fp.c_str(), "rb")))
return false;
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
/* determine size */
fseek(fd, 0, SEEK_END);
size = ftell(fd);
fseek(fd, 0, SEEK_SET);
SHA1_Init(sha_ctx);
while((len = fread(gblBuf,1, 512, fd)) > 0)
{
SHA1_Update(sha_ctx, gblBuf, len);
}
/* reading failed for some reason */
if (ferror(fd))
{
delete sha_ctx;
fclose(fd);
return false;
}
SHA1_Final(&sha_buf[0], sha_ctx);
std::ostringstream tmpout;
for(int i = 0; i < SHA_DIGEST_LENGTH; i++)
{
tmpout << std::setw(2) << std::setfill('0') << std::hex << (unsigned int) (sha_buf[i]);
}
hash = tmpout.str();
delete sha_ctx;
fclose(fd);
return true;
}
bool RsDirUtil::renameWideFile(const std::wstring& from, const std::wstring& to)
{
int loops = 0;
#if defined(WIN32) || defined(MINGW) || defined(__CYGWIN__)
#ifdef WIN_CROSS_UBUNTU
std::wstring f,t ;
for(int i=0;i<from.size();++i) f.push_back(from[i]) ;
for(int i=0;i<to.size();++i) t.push_back(to[i]) ;
#else
std::wstring f(from),t(to) ;
#endif
while (!MoveFileEx(f.c_str(), t.c_str(), MOVEFILE_REPLACE_EXISTING))
#else
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
std::string f(from.begin(), from.end());
std::string t(to.begin(), to.end());
while (rename(f.c_str(), t.c_str()) < 0)
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
#endif
{
#ifdef WIN32
if (GetLastError() != ERROR_ACCESS_DENIED)
#else
if (errno != EACCES)
#endif
/* set errno? */
return false ;
#ifdef WIN32
Sleep(100000); /* us */
#else
usleep(100000); /* us */
#endif
if (loops >= 30)
return false ;
loops++;
}
return true ;
}

View File

@ -38,9 +38,9 @@ std::string getTopDir(std::string);
std::string getRootDir(std::string);
std::string removeRootDir(std::string path);
std::string removeTopDir(std::string dir);
std::string removeRootDirs(std::string path, std::string root);
// Renames file from to file to. Files should be on the same file system.
// returns true if succeed, false otherwise.
bool renameFile(const std::string& from,const std::string& to) ;
@ -58,6 +58,30 @@ bool hashFile(std::string filepath,
bool getFileHash(std::string filepath,
std::string &hash, uint64_t &size);
std::wstring getWideTopDir(std::wstring);
std::wstring getWideRootDir(std::wstring);
std::wstring removeWideRootDir(std::wstring path);
std::wstring removeWideTopDir(std::wstring dir);
std::wstring removeWideRootDirs(std::wstring path, std::wstring root);
// Renames file from to file to. Files should be on the same file system.
// returns true if succeed, false otherwise.
bool renameWideFile(const std::wstring& from,const std::wstring& to) ;
int breakupWideDirList(std::wstring path,
std::list<std::wstring> &subdirs);
bool checkWideDirectory(std::wstring dir);
bool checkWideCreateDirectory(std::wstring dir);
bool cleanupWideDirectory(std::wstring dir, std::list<std::wstring> keepFiles);
bool hashWideFile(std::wstring filepath,
std::wstring &name, std::string &hash, uint64_t &size);
bool getWideFileHash(std::wstring filepath,
std::string &hash, uint64_t &size);
}