⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpfpackets.cpp

📁 vc环境下的pgp源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		c = HPPUNESCAPE(c);
	}
	if(reliable)
		crc32 = updatecrc32(c, crc32);
	else
		crc = updatecrc16(c, crc);
	seqbyte = c;
	
	// Get body of packet
	p = *buffer;
	outlen = 0;

	inlen = mInputTail-mInputHead;
	for (;;)
	{
		if(!inlen--)
		{
			if(GetData() < 0)
				goto abort;
			inlen = mInputTail-mInputHead-1;
		}
		c = *mInputHead++;
		if(HPPNEEDSESCAPE(c))
		{
			if(c == HPPPACKETDELIM)
				break;	// End of packet!
			if(!inlen--)
			{
				if(GetData() < 0)
					goto abort;
				inlen = mInputTail-mInputHead-1;
			}
			c = *mInputHead++;
			if(c == HPPPACKETDELIM)
			{
				if(gPacketWatch)
					gPacketWatch->GotPacket(FALSE);	// Bad packet
				goto packetstart;
			}
			c = HPPUNESCAPE(c);
		}
		if(++outlen > HPPMAXPKTLEN + 2)	// Packet too long - skip
			goto packetfind;
		*p++ = c;
		if(reliable)
			crc32 = updatecrc32(c, crc32);
		else
			crc = updatecrc16(c, crc);
	}
	// We now have a complete packet
	if(mAbort)
		goto abort;
	if((reliable && ((crc32 != 0xDEBB20E3) || (outlen < 4))) ||
		(!reliable && ((crc != 0) || (outlen < 2))))	// Bad CRC?
	{
		if(gPacketWatch)
			gPacketWatch->GotPacket(FALSE);	// Bad packet
		goto packetstart;
	}
	mInputHead--;		// Back up so next invocation can find packet delim
	
	*len = outlen - (reliable ? 4 : 2);      // Chop off CRC, leaving only user data
	// Find the last encountered sequence number
	if(*type >= RELIABLESTART)
	{
		if(*type == _hpt_File)
			sequence = sRFileSequence;
		else
			sequence = sRControlSequence;
	}
	else
		sequence = mSequence;
	
	// Find the full sequence number of the current packet
	sequence += (long)(signed char)(seqbyte-sequence);
	*seq = sequence;
	
	// Okay, now decrypt the thing
	if((*type != _hpt_ACK) && (*type != _hpt_Control))
	{
		// Create counter mode iv
		iv[0] = (uchar)*type;
		iv[1] = 0;
		LONG_TO_BUFFER(sequence, &iv[2]);
	
		mRXKeyChangeMutex.Wait();
		if(mDecryptor)
		{
			mDecryptor->Decrypt(*buffer, *len, iv);
			crypted = TRUE;
		}
		mRXKeyChangeMutex.Signal();
	}
	return crypted;
abort:
	safe_free(*buffer);
	*buffer = NIL;
	*len = 0;
	*type = (enum HPPPacketType)0;
	return crypted;
}

short
CPFPacketsIn::GetData(void)
{
	long read;
	short channel;

	do {
		if(mAbort)
			return -1;
#ifdef PGP_WIN32
		// sleeps until a character arrives or our abort event is triggered
		if (!ResetEvent(mAbortEvent))
		{
			DWORD error = GetLastError();
			char	str[100];					

			sprintf(str, "Abort event error %ld",  (error));
			pgp_errstring(str);				

		}
		short result = mTransport->SleepForData(&mAbortEvent);
		if (result != 0)
		{
			ResetEvent(mAbortEvent);
			return -1;	// error (< 0) or aborted (> 0)
		}
		ResetEvent(mAbortEvent);
#else
		(Yield)();
#endif	// PGP_WIN32
		read = mTransport->Read(mInputBuffer, HPPBUFFERSIZE, &channel);
	} while (!read);
	mInputHead = mInputBuffer;
	mInputTail = mInputBuffer + read;
	return 0;
}

//	Datagram style packet format
//	
//	Type		:	1 byte
//	Sequence	:	2 bytes
//	Data		:	<=	HPPMAXPKTLEN(1024)
//  CRC     	:   4 bytes (reliable packets only)
//
//	SendPacket is designed to skip bit stuffing in favor of the
//	above format for use over networks and other channels where
//	bit stuffing is pointless or redundant.

void
CPFPacketsOut::SendPacket(enum HPPPacketType type, ulong seq, long len, uchar *data)
{
	HPPReliablePacket *hppr, *walk;
	uchar *sendbuf, *p, fb;
	ulong crc32, timestamp;
	uchar iv[6];
	ushort seqshort;
	
	pgpAssert(len <= HPPMAXPKTLEN);
	mTransport->WaitAsync(&mAsyncs[mNextAsync]);
	mAsyncs[mNextAsync].buffer = sendbuf = (uchar *)safe_malloc(1024+7);
	p = sendbuf;
	*p++ = type;
	seqshort = (ushort)seq;
	SHORT_TO_BUFFER(seqshort, p);	p+= 2;
	fb = *data;
	if(type == _hpt_Voice)
	{
		timestamp = pgp_milliseconds();
		LONG_TO_BUFFER(timestamp, p);	p+=4;
		pgp_memcpy(p, data, len);		p+=len;
		len += 4;
	}
	else
	{
		pgp_memcpy(p, data, len);	p+=len;
	}
	if((type != _hpt_ACK) && (type != _hpt_Control))
	{
		mTXKeyChangeMutex.Wait();
		// Setup the counter for counter mode
		// Counter format:
		// Byte 1		Packet Type
		// Byte 2		Packet Counter, mod 2^40
		// Bytes 7-8	Cipher block counter
		
		iv[0] = (uchar)type;
		iv[1] = 0;
		LONG_TO_BUFFER(seq, &iv[2]);
		if(mEncryptor)
			mEncryptor->Encrypt(sendbuf+3, len, iv);
		mTXKeyChangeMutex.Signal();
	}
	len+=3;
	if(type >= RELIABLESTART)
	{
		crc32 = CalcCRC32(sendbuf, len);
		LONG_TO_BUFFER(crc32, p);	p+=4;
		len+=4;
		hppr = (HPPReliablePacket *)safe_malloc(sizeof(HPPReliablePacket));
		memset(hppr, 0, sizeof(HPPReliablePacket));
		sInOutMutex->Wait();
		if(type == _hpt_File)
		{
			if(sFileReliables)
			{
				for(walk = sFileReliables;walk->next;walk=walk->next)
					;
				walk->next = hppr;
			}
			else
				sFileReliables = hppr;
		}
		else
		{
			if(sControlReliables)
			{
				for(walk = sControlReliables;walk->next;walk=walk->next)
					;
				walk->next = hppr;
			}
			else
				sControlReliables = hppr;
		}
		hppr->type = type;
		hppr->seq = seq;
		hppr->subType=fb;
		hppr->firstXmitTime = hppr->lastXmitTime = pgp_getticks();
		hppr->data = sendbuf;
		safe_increaseCount(sendbuf);
		hppr->len = (short) len;
		sInOutMutex->Signal();
	}
	mTransport->WriteAsync(len, (type==_hpt_Voice)? _pfc_Media : _pfc_Control, &mAsyncs[mNextAsync++]);
	mNextAsync %= NUMHPPASYNCS;
	if(gPacketWatch)
		gPacketWatch->SentPacket();
}

//	The GetPacket routine assumes that all Read calls return an HPP
//	packet.  A lower layer is expected to be doing the packetization.
//	This is the case under Internet UDP and AppleTalk DDP.

Boolean
CPFPacketsIn::GetPacket(enum HPPPacketType *type, uchar **buffer, short *len, ulong *seq)
{
	long read, dlen, baavg, baskew;
	ulong crc32, pkcrc32, sequence, timestamp, timestampnow;
	uchar iv[6];
	ushort seqshort;
	short channel;
	Boolean goodcrc, crypted=FALSE;
	
	*buffer = NIL;
	while(!mAbort)
	{
		read = mTransport->Read(mInputBuffer, HPPBUFFERSIZE, &channel);
		if(read)
		{
			goodcrc = FALSE;
			if(mInputBuffer[0] >= RELIABLESTART)
			{
				// we only CRC control packets in packet mode
				if(read >= 6)
				{
					crc32 = CalcCRC32(mInputBuffer, read - 4);
					BUFFER_TO_LONG(mInputBuffer + read - 4, pkcrc32);
					if(crc32 == pkcrc32)
						goodcrc = TRUE;
					read -=4;
				}
			}
			else
				goodcrc = TRUE;
			dlen = read - 3;        // Allow for type and sequence bytes
			if(goodcrc && (mInputBuffer[0] <= LASTPACKETTYPE) &&
				(dlen <= HPPMAXPKTLEN))
			{
				*type = (enum HPPPacketType)mInputBuffer[0];
				if((*buffer = (uchar*)safe_malloc(dlen)) != NULL)
				{
					BUFFER_TO_SHORT(&mInputBuffer[1], seqshort);
					
					// Find the last encountered sequence number
					if(*type >= RELIABLESTART)
					{
						if(*type == _hpt_File)
							sequence = sRFileSequence;
						else
							sequence = sRControlSequence;
					}
					else
						sequence = mSequence;
					
					// Find the full sequence number of the current packet
					sequence += (long)(signed short)(seqshort - sequence);
					*seq = sequence;
					if((*type != _hpt_ACK) && (*type != _hpt_Control))
					{
						iv[0] = (uchar)*type;
						iv[1] = 0;	// +++++ should be overflow bits
						LONG_TO_BUFFER(sequence, &iv[2]);
						mRXKeyChangeMutex.Wait();
						if(mDecryptor)
						{
							mDecryptor->Decrypt(mInputBuffer + 3, dlen, iv);
							crypted = TRUE;
						}
						mRXKeyChangeMutex.Signal();
					}
					if((*type == _hpt_Voice) && (dlen > 5))
					{
						dlen-=4;
						*len = (short) dlen;
						pgp_memcpy(*buffer, mInputBuffer + 7, dlen);
						BUFFER_TO_LONG(mInputBuffer + 3, timestamp);
						timestampnow = pgp_milliseconds();
						baskew = timestampnow-timestamp;
						if(mJitterCount > 3)
							sSkew += (baskew-sSkew)/8;
						else
							sSkew = baskew;
						baavg = labs(baskew-sSkew);
						sJVariance += (baavg-sJVariance)/16;
						sJitter = sJVariance * 2;		// old: sJVariance * 2;
						// max = sJitter + sSkew;
						// if baskew > max, it's late!
						if(baskew > sJitter + sSkew)
						{
							if(++mLateTrack > 2)
							{
								//if(sLastSRR + 5000 < pgp_getticks())
								//	SendRR();
								mLateTrack = 0;
							}
						}
						else
							mLateTrack = 0;
						if(mJitterCount<10)
							mJitterCount++;
						else
						{
							mSoundOutput->SetJitter(sJitter);
							gPacketWatch->SetJitter(sJitter);
						}
					}
					else
					{
						*len = (short) dlen;
						pgp_memcpy(*buffer, mInputBuffer + 3, dlen);
					}
					return crypted;
				}
			}
			else
				gPacketWatch->GotPacket(FALSE); // Log bad packet
		}
		(Yield)();
	}
	return crypted;
}

void
CPFPacketsIn::DeliverPacket(enum HPPPacketType packetType, uchar *packet, short packetLen)
{
	HPPReliablePacket *hppr, *lhpr;
	enum HPPPacketType ackType;
	ulong sq, rttVal;
	ushort seqshort;
	uchar seqbyte;

	switch(packetType)
	{
		case _hpt_ACK:
			ackType = (enum HPPPacketType)((ulong)*packet);
			sInOutMutex->Wait();
			if(ackType == _hpt_File)
			{
				hppr = sFileReliables;
				sq = sSFileSequence;
			}
			else
			{
				hppr = sControlReliables;
				sq = sSControlSequence;
			}
			if(mPacketMode)
			{
				BUFFER_TO_SHORT(packet+1, seqshort);
				//DebugLog("ACK at %ld, on %d", sq, seqshort);
				//CStatusPane::GetStatusPane()->AddStatus(0, "Rcvd ACK at %ld, on %ld", sq, seqshort);
				sq += (long)(signed short)(seqshort - sq);
			}
			else
			{
				seqbyte = *(packet+1);
				sq += (long)(signed char)(seqbyte-sq);
			}
			for(lhpr=NIL;hppr;hppr=hppr->next)
			{
				if((hppr->type == ackType) && (hppr->seq == sq))
				{
					// send ack notification back to control,
					// and include the first byte of the
					// packet so control can identify it.
					if(ackType != _hpt_File)
						mControlQueue->Send(_mt_ack, (void *)hppr->subType);
					if(lhpr)
						lhpr->next = hppr->next;
					else
					{
						if(ackType == _hpt_File)
							sFileReliables = hppr->next;
						else
							sControlReliables = hppr->next;
					}
					if(!hppr->retransmits)
					{
						// Update ACK timeout low-pass filter
						
						sInOutMutex->Wait();
						sACKWaitAverage = (ulong)((0.9 * (float)sACKWaitAverage) +
											(0.1 * (float)(pgp_getticks() - hppr->firstXmitTime)));
						sACKWaitTime = sACKWaitAverage * 2;
						sInOutMutex->Signal();
					}
					else
					{
					}
					safe_free(hppr->data);
					safe_free(hppr);
				}
				lhpr = hppr;
			}
			sInOutMutex->Signal();
			safe_free(packet);
			break;
		case _hpt_Voice:
			mSoundOutQueue->Send(_mt_voicePacket, packet, packetLen, TRUE);
			break;
		case _hpt_Control:
			if(mDecryptor)
			{
				safe_free(packet);
				if(gPacketWatch)
					gPacketWatch->GotPacket(FALSE);
				break;	//ignore unencrypted pkts on encrypted link
			}
		case _hpt_ControlEncrypt:
			mControlQueue->Send(_mt_controlPacket, packet, packetLen, TRUE);
			break;
		case _hpt_RTT:
			BUFFER_TO_LONG(&packet[1], rttVal);
			if(packet[0] == mPFWindow->GetControlThread()->IsOriginator())
			{
				// Make sure this wasn't some RTT packet floating
				// around the network we sent a long time ago
				if(rttVal == sRTTSequence)
				{
#ifdef	PGP_MACINTOSH
					if(UEnvironment::HasFeature(env_HasOpenTransport))
						gPacketWatch->SetRTTime(OTElapsedMilliseconds(&sOTRTTBase));
					else
						gPacketWatch->SetRTTime(pgp_getticks() - sRTTBase);
#else
					gPacketWatch->SetRTTime(pgp_getticks() - sRTTBase);
#endif
				}
				safe_free(packet);
			}
			else
				mOutQueue->Send(_mt_rtt, packet, packetLen, TRUE);
			break;
		case _hpt_ReceptionReport:
#ifdef BETA
			//CStatusPane::GetStatusPane()->AddStatus(0,
			//	"Sound is late on the remote side, adjusting bandwidth.");
#endif
			/*sInOutMutex->Wait();
			sBandwidthcps = sBandwidthcps / 5 * 4;
			sBandwidthpp = sBandwidthcps / (1000 / sIntervalms);
			gPacketWatch->SetBandwidth(sBandwidthcps);
			sLastRRR = pgp_getticks();
			sInOutMutex->Signal();*/
			safe_free(packet);
			break;
		case _hpt_File:
			if(mXferQueue)
				mXferQueue->Send(_mt_filePacket, packet, packetLen, TRUE);
			else
				safe_free(packet);
			break;
		default:
			safe_free(packet);
			break;
	}
}

void
CPFPacketsIn::SendRR()
{
	/*
	+++++
	uchar *p, *e;
	
	p = e = (uchar *)safe_malloc(1);
	*e++ = 0;
	mOutQueue->Send(_mt_rr, p, 1, TRUE);*/
}

void
CPFPacketsIn::AckPacket(enum HPPPacketType packetType, ulong seq)
{
	uchar *p, *ackpkt, seqbyte;
	ushort seqshort;
	
	if(mPacketMode)
	{
		// We use 16 bit sequence numbers in packet mode (over IP and AppleTalk)
		p = ackpkt = (uchar *)safe_malloc(3);
		*p++ = packetType;
		seqshort = (unsigned short) seq & 0xFFFF;
		SHORT_TO_BUFFER(seqshort, p);
		mOutQueue->Send(_mt_ack, ackpkt, 3, TRUE);
	}
	else
	{
		// We use 8 bit sequence numbers in serial mode
		p = ackpkt = (uchar *)safe_malloc(2);
		*p++ = packetType;
		seqbyte = (unsigned char) seq & 0xFF;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -