Beispiel #1
0
// Get next peer manager packet. Also encapsulates packets for relaying if necessary. Returns length if successful.
static int peermgtGetNextPacket(struct s_peermgt *mgt, unsigned char *pbuf, const int pbuf_size, struct s_peeraddr *target) {
	int tnow;
	int outlen;
	int relayid;
	int relayct;
	int relaypeerid;
	int depth;
	struct s_packet_data data;
	tnow = utilGetTime();
	while((outlen = (peermgtGetNextPacketGen(mgt, pbuf, pbuf_size, tnow, target))) > 0) {
		depth = 0;
		while(outlen > 0) {
			if(depth < peermgt_DECODE_RECURSION_MAX_DEPTH) { // limit encapsulation depth
				if(!peeraddrIsInternal(target)) {
					// address is external, packet is ready for sending
					return outlen;
				}
				else {
					if(((packet_PEERID_SIZE + outlen) < peermgt_MSGSIZE_MAX) && (peeraddrGetIndirect(target, &relayid, &relayct, &relaypeerid))) {
						// address is indirect, encapsulate packet for relaying
						if(peermgtIsActiveRemoteIDCT(mgt, relayid, relayct)) {
							// generate relay-in packet
							utilWriteInt32(&mgt->relaymsgbuf[0], relaypeerid);
							memcpy(&mgt->relaymsgbuf[packet_PEERID_SIZE], pbuf, outlen);
							data.pl_buf = mgt->relaymsgbuf;
							data.pl_buf_size = packet_PEERID_SIZE + outlen;
							data.peerid = mgt->data[relayid].remoteid;
							data.seq = ++mgt->data[relayid].remoteseq;
							data.pl_length = packet_PEERID_SIZE + outlen;
							data.pl_type = packet_PLTYPE_RELAY_IN;
							data.pl_options = 0;

							// encode relay-in packet
							outlen = packetEncode(pbuf, pbuf_size, &data, &mgt->ctx[relayid]);
							if(outlen > 0) {
								mgt->data[relayid].lastsend = tnow;
								*target = mgt->data[relayid].remoteaddr;
							}
							else {
								outlen = 0;
							}
						}
						else {
							outlen = 0;
						}
					}
					else {
						outlen = 0;
					}
				}
				depth++;
			}
			else {
				outlen = 0;
			}
		}
	}
	return 0;
}
/// Main processing method
void Dvbt1RSEncoderComponent::process()
{
  // request input
  DataSet< uint8_t >* in = NULL;
  getInputDataSet("input1", in);
  
  // calculate sizes
  int insize = in ? (int) in->data.size() : 0;
  int numpacks = (insize + tsOffset_) / TS_PACKET_SIZE;
  int outsize = numpacks * RS_PACKET_SIZE;

  // request output
  DataSet< uint8_t >* out = NULL;
  getOutputDataSet("output1", out, outsize);
 		
  // print debug info
  if(debug_x)
    LOG(LINFO) << "in/out: " << insize + tsOffset_ << "(" << insize << "+" << tsOffset_ << ")/" << outsize;

  // fill the messagewords
  for(ByteVecIt init = in->data.begin(), outit = out->data.begin(); init < in->data.end(); init++)
  {
  
    // copy in reverse order
    rsCodeWord_[TS_PACKET_SIZE - 1 - tsOffset_] = *init;
    
    // trigger encoding
    if(++tsOffset_ == TS_PACKET_SIZE)
    {
      int status = packetEncode(rsCodeWord_, rsCodeWord_ + T1_KK);
			if (status)
				LOG(LERROR) << "Problem encoding a R-S word";

      // copy information part
      for(int b = 0; b < TS_PACKET_SIZE; b++, outit++)
        *outit = rsCodeWord_[TS_PACKET_SIZE - 1 - b];
			
			// copy parity part
			for(int b = 0; b < T1_NN_KK; b++, outit++)
				*outit = rsCodeWord_[T1_NN - 1 - b];
				
      // reset TS pointer
      tsOffset_ = 0;
    }
  }

  //Copy the timestamp and sample rate for the DataSets
  out->timeStamp = in->timeStamp;
  out->sampleRate = in->sampleRate;

  // release input and output
  releaseInputDataSet("input1", in);
  releaseOutputDataSet("output1", out);
}
Beispiel #3
0
static int packetTestsuiteMsg(const int random_msg) {
	unsigned char plbuf[packetTestsuite_PLBUF_SIZE];
	unsigned char plbufdec[packetTestsuite_PLBUF_SIZE];
	struct s_packet_data testdata = { .pl_buf_size = packetTestsuite_PLBUF_SIZE, .pl_buf = plbuf };
	struct s_packet_data testdatadec = { .pl_buf_size = packetTestsuite_PLBUF_SIZE, .pl_buf = plbufdec };
	unsigned char pkbuf[packetTestsuite_PKBUF_SIZE];
	struct s_crypto ctx[2];
	unsigned char secret[64];
	unsigned char nonce[16];
	struct s_seq_state seqstate;
	char str[4096];
	int len;
	
	memset(secret, 23, 64);
	memset(nonce, 5, 16);
	
	cryptoCreate(ctx, 2);
	
	if(!cryptoSetKeys(&ctx[0], 1, secret, 64, nonce, 16)) return 0;
	if(!cryptoSetKeys(&ctx[1], 1, secret, 64, nonce, 16)) return 0;

	seqInit(&seqstate, 0);
	
	memset(plbuf, 0, packetTestsuite_PLBUF_SIZE);
	if(random_msg) RAND_pseudo_bytes(plbuf, packetTestsuite_PLBUF_SIZE);
	else strcpy((char *)plbuf, "moo");
	len = packetTestsuite_PLBUF_SIZE;
	testdata.pl_length = len;
	testdata.pl_type = 0;
	testdata.pl_options = 0;
	testdata.peerid = plbuf[0];
	testdata.seq = 1;
	utilByteArrayToHexstring(str, 4096, plbuf, len);
	printf("%s (len=%d, peerid=%d) -> ", str, len, testdata.peerid);
	len = packetEncode(pkbuf, packetTestsuite_PKBUF_SIZE, &testdata, &ctx[0]);
	if(!(len > 0)) return 0;
	utilByteArrayToHexstring(str, 4096, pkbuf, len);
	printf("%s (%d) -> ", str, len);
	if(!(packetDecode(&testdatadec, pkbuf, len, &ctx[1], &seqstate))) return 0;
	if(!(testdatadec.pl_length > 0)) return 0;
	if(!(testdatadec.peerid == plbuf[0])) return 0;
	if(!memcmp(testdatadec.pl_buf, testdata.pl_buf, packetTestsuite_PLBUF_SIZE) == 0) return 0;
	utilByteArrayToHexstring(str, 4096, testdatadec.pl_buf, testdatadec.pl_length);
	printf("%s (len=%d, peerid=%d)\n", str, testdatadec.pl_length, testdatadec.peerid);
	
	cryptoDestroy(ctx, 2);

	return 1;
}
Beispiel #4
0
// Generate next peer manager packet. Returns length if successful.
static int peermgtGetNextPacketGen(struct s_peermgt *mgt, unsigned char *pbuf, const int pbuf_size, const int tnow, struct s_peeraddr *target) {
	int used = mapGetKeyCount(&mgt->map);
	int len;
	int outlen;
	int fragoutlen;
	int peerid;
	int relayid;
	int usetargetaddr;
	int i;
	int fragcount;
	int fragpos;
	const int plbuf_size = peermgt_MSGSIZE_MIN;
	unsigned char plbuf[plbuf_size];
	struct s_msg authmsg;
	struct s_packet_data data;
	
	// send out user data
	outlen = mgt->outmsg.len;
	fragoutlen = mgt->fragoutsize;
	if(outlen > 0 && (!(fragoutlen > 0))) {
		if(mgt->outmsgbroadcast) { // get PeerID for broadcast message
			do {
				peerid = peermgtGetNextID(mgt);
				mgt->outmsgbroadcastcount++;
			}
			while((!(peermgtIsActiveRemoteID(mgt, peerid) && peermgtGetRemoteFlag(mgt, peerid, peermgt_FLAG_USERDATA))) && (mgt->outmsgbroadcastcount < used));
			if(mgt->outmsgbroadcastcount >= used) {
				mgt->outmsgbroadcast = 0;
				mgt->outmsg.len = 0;
			}
		}
		else { // get PeerID for unicast message
			peerid = mgt->outmsgpeerid;
			mgt->outmsg.len = 0;
		}
		if(peermgtIsActiveRemoteID(mgt, peerid)) {  // check if session is active
			if(peermgtGetRemoteFlag(mgt, peerid, peermgt_FLAG_USERDATA)) {
				if((mgt->fragmentation > 0) && (outlen > peermgt_MSGSIZE_MIN)) {
					// start generating fragmented userdata packets
					mgt->fragoutpeerid = peerid;
					mgt->fragoutcount = (((outlen - 1) / peermgt_MSGSIZE_MIN) + 1); // calculate number of fragments
					mgt->fragoutsize = outlen;
					fragoutlen = outlen;
					mgt->fragoutpos = 0;
				}
				else {
					// generate userdata packet
					data.pl_buf = mgt->outmsg.msg;
					data.pl_buf_size = outlen;
					data.peerid = mgt->data[peerid].remoteid;
					data.seq = ++mgt->data[peerid].remoteseq;
					data.pl_length = outlen;
					data.pl_type = packet_PLTYPE_USERDATA;
					data.pl_options = 0;
					len = packetEncode(pbuf, pbuf_size, &data, &mgt->ctx[peerid]);
					if(len > 0) {
						mgt->data[peerid].lastsend = tnow;
						*target = mgt->data[peerid].remoteaddr;
						return len;
					}
				}
			}
		}
	}

	// send out fragments
	if(fragoutlen > 0) {
		fragcount = mgt->fragoutcount;
		fragpos = mgt->fragoutpos;
		peerid = mgt->fragoutpeerid;
		if(peermgtIsActiveRemoteID(mgt, peerid)) {  // check if session is active
			// generate fragmented packet
			data.pl_buf = &mgt->outmsg.msg[(fragpos * peermgt_MSGSIZE_MIN)];
			if(fragoutlen > peermgt_MSGSIZE_MIN) {
				// start or middle fragment
				data.pl_buf_size = peermgt_MSGSIZE_MIN;
				data.pl_length = peermgt_MSGSIZE_MIN;
				mgt->fragoutsize = (fragoutlen - peermgt_MSGSIZE_MIN);
			}
			else {
				// end fragment
				data.pl_buf_size = fragoutlen;
				data.pl_length = fragoutlen;
				mgt->fragoutsize = 0;
			}
			data.peerid = mgt->data[peerid].remoteid;
			data.seq = ++mgt->data[peerid].remoteseq;
			data.pl_type = packet_PLTYPE_USERDATA_FRAGMENT;
			data.pl_options = (fragcount << 4) | (fragpos);
			len = packetEncode(pbuf, pbuf_size, &data, &mgt->ctx[peerid]);
			mgt->fragoutpos = (fragpos + 1);
			if(len > 0) {
				mgt->data[peerid].lastsend = tnow;
				*target = mgt->data[peerid].remoteaddr;
				return len;
			}
		}
		else {
			// session not active anymore, abort sending fragments
			mgt->fragoutsize = 0;
		}
	}

	// send out request-response packet
	outlen = mgt->rrmsg.len;
	if(outlen > 0) {
		peerid = mgt->rrmsgpeerid;
		usetargetaddr = mgt->rrmsgusetargetaddr;
		mgt->rrmsg.len = 0;
		mgt->rrmsgusetargetaddr = 0;
		if((outlen < peermgt_MSGSIZE_MAX) && (peermgtIsActiveRemoteID(mgt, peerid))) {  // check if session is active
			data.pl_buf = mgt->rrmsg.msg;
			data.pl_buf_size = peermgt_MSGSIZE_MAX;
			data.pl_length = outlen;
			data.pl_type = mgt->rrmsgtype;
			data.pl_options = 0;
			data.peerid = mgt->data[peerid].remoteid;
			data.seq = ++mgt->data[peerid].remoteseq;

			len = packetEncode(pbuf, pbuf_size, &data, &mgt->ctx[peerid]);
			if(len > 0) {
				if(usetargetaddr > 0) {
					*target = mgt->rrmsgtargetaddr;
				}
				else {
					mgt->data[peerid].lastsend = tnow;
					*target = mgt->data[peerid].remoteaddr;
				}
				return len;
			}
		}
	}

	// send peerinfo to peers
	for(i=0; i<used; i++) {
		peerid = peermgtGetNextID(mgt);
		if(peerid > 0) {
			if((tnow - mgt->data[peerid].lastrecv) < peermgt_RECV_TIMEOUT) { // check if session has expired
				if(mgt->data[peerid].state == peermgt_STATE_COMPLETE) {  // check if session is active
					if(((tnow - mgt->data[peerid].lastsend) > peermgt_KEEPALIVE_INTERVAL) || ((tnow - mgt->data[peerid].lastpeerinfo) > peermgt_PEERINFO_INTERVAL)) { // check if we should send peerinfo packet
						data.pl_buf = plbuf;
						data.pl_buf_size = plbuf_size;
						data.peerid = mgt->data[peerid].remoteid;
						data.seq = ++mgt->data[peerid].remoteseq;
						peermgtGenPacketPeerinfo(&data, mgt);
						len = packetEncode(pbuf, pbuf_size, &data, &mgt->ctx[peerid]);
						if(len > 0) {
							mgt->data[peerid].lastsend = tnow;
							mgt->data[peerid].lastpeerinfo = tnow;
							*target = mgt->data[peerid].remoteaddr;
							return len;
						}
					}
				}
			}
			else {
				peermgtDeleteID(mgt, peerid);
			}
		}
	}
	
	// send auth manager message
	if(authmgtGetNextMsg(&mgt->authmgt, &authmsg, target)) {
		data.pl_buf = authmsg.msg;
		data.pl_buf_size = authmsg.len;
		data.peerid = 0;
		data.seq = 0;
		data.pl_length = authmsg.len;
		if(data.pl_length > 0) {
			data.pl_type = packet_PLTYPE_AUTH;
			data.pl_options = 0;
			len = packetEncode(pbuf, pbuf_size, &data, &mgt->ctx[0]);
			if(len > 0) {
				mgt->data[0].lastsend = tnow;
				return len;
			}
		}
	}
	
	// connect new peer
	if((authmgtUsedSlotCount(&mgt->authmgt) < ((authmgtSlotCount(&mgt->authmgt) / 4) * 3)) && ((tnow - mgt->lastconnect) > peermgt_NEWCONNECT_INTERVAL)) {
		i = nodedbNextID(&mgt->nodedb, peermgt_NEWCONNECT_MAX_AGE, 0, 1);
		if(!(i < 0)) {
			peerid = peermgtGetID(mgt, nodedbGetNodeID(&mgt->nodedb, i));
			if(peerid < 0) { // check if node is already connected
				// node is not connected yet
				if(peermgtConnect(mgt, nodedbGetNodeAddress(&mgt->nodedb, i))) { // try to connect
					if(peermgtConnect(mgt, nodedbGetIndirectNodeAddress(&mgt->nodedb, i))) { // try to connect via relay
						relayid = 0; // on success, dont change indirect entry in NodeDB
					}
					else {
						relayid = -1; // on failure, delete indirect entry in NodeDB
					}
					nodedbUpdate(&mgt->nodedb, nodedbGetNodeID(&mgt->nodedb, i), NULL, 0, 0, 1, relayid, 0, 0);
					mgt->lastconnect = tnow;
				}
			}
			else {
				// node is already connected
				if(peeraddrIsInternal(&mgt->data[peerid].remoteaddr)) {
					peermgtSendPingToAddr(mgt, NULL, peerid, mgt->data[peerid].conntime, nodedbGetNodeAddress(&mgt->nodedb, i)); // try to switch peer to a direct connection
					nodedbUpdate(&mgt->nodedb, nodedbGetNodeID(&mgt->nodedb, i), NULL, 0, 0, 1, 0, 0, 0);
					mgt->lastconnect = tnow;
				}
			}
		}
	}
	
	return 0;
}