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

📄 cpftinternet.cpp

📁 vc环境下的pgp源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
								remoteName[0]=0;
								if(len > 2)
								{
									if((slen = *p++) && (len-3 >= (ulong)slen))
									{
										if(slen > 63)
											slen = 63;
										pgp_memcpy(remoteName, p, slen);
										remoteName[slen]=0;
										mPFWindow->GetControlThread()->SetRemoteName(remoteName);
									}
								}
								SetState(_cs_calldetected);
								inadr.s_addr = mLastAddress.sin_addr.s_addr;
								strcpy(remoteDotName, inet_ntoa(inadr));
								nextRingTime = pgp_getticks();
								rings = 0;
								sendResp = TRUE;
								noted = FALSE;
							}
							break;
						case _ptip_Probe:
							sendResp = TRUE;
							break;
						case _ptip_Message:
							ReceiveUDPMsg(p, len -2);
							break;
					}
			}
			if(sendResp)
			{
				responsepkt[0] = _hpt_Setup;
				responsepkt[1] = _ptip_ProbeResponse;	resplen = 2;
				if(gPGFOpts.popt.idUnencrypted && gPGFOpts.popt.idOutgoing &&
					gPGFOpts.popt.identity[0])
				{
					resplen+= (responsepkt[2] = strlen(gPGFOpts.popt.identity)) + 1;
					strcpy(&responsepkt[3], gPGFOpts.popt.identity);
				}
				WriteBlockTo(responsepkt, &resplen, &mLastAddress);
				sendResp = FALSE;
			}
			if(!goodaddr)
				pgp_memcpy(&mLastAddress, &savedAddress, sizeof(savedAddress));
			::Sleep(0);
		} while(!mAbort);
		if(mState != _cs_connected)
		{
			//WinSock 1.1 apparently didn't bother to include an unbind
			//call, so we have to hack it by killing the socket and recreating.
			closesocket(mSocket);
			mSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
		}
	}
	if(!mAnswer && mAbort)
		result = _pge_InternalAbort;
	mAnswer = FALSE;
	mTMutex->Signal();
	return result;
}

PGErr
CPFTInternet::Reset()
{
	mAbort = FALSE;
	return 0;
}

long
CPFTInternet::Read(void *data, long max, short *channel)
{
	long len = 0, rdlen;
	fd_set rfds;
	struct timeval tv;
	int fromlen, err, rcvd=0;	
	char rdpkt[128];
	SOCKET rcvSock;

	// currently we poll WinSock using select.  Alternatives
	// to this include using the massive async hack from
	// WinSock 1.1 or the message system which will be
	// available in WinSock 2.  The best elegant method seems
	// to be to detect WinSock2 and use it if available,
	// otherwise use this 1.1 polling stuff.

	// return one packet if available
	if(mMSocket != INVALID_SOCKET)
	{
		memset(&tv, 0, sizeof(struct timeval));
		FD_ZERO(&rfds);
		FD_SET(mMSocket, &rfds);
		err = select(1, &rfds, NIL, NIL, &tv);
		if(err > 0)
		{
			rcvSock = mMSocket;
			*channel = _pfc_Media;
			rcvd=1;
		}
	}
	if(!rcvd && mSocket != INVALID_SOCKET)
	{
		memset(&tv, 0, sizeof(struct timeval));
		FD_ZERO(&rfds);
		FD_SET(mSocket, &rfds);
		err = select(1, &rfds, NIL, NIL, &tv);
		if(err > 0)
		{
			rcvSock = mSocket;
			*channel = _pfc_Control;
			rcvd=1;
		}
	}
	if(!rcvd && mMCSocket != INVALID_SOCKET)
	{
		memset(&tv, 0, sizeof(struct timeval));
		FD_ZERO(&rfds);
		FD_SET(mMCSocket, &rfds);
		err = select(1, &rfds, NIL, NIL, &tv);
		if(err > 0)
		{
			rcvSock = mMCSocket;
			*channel = _pfc_MediaControl;
			rcvd=1;
		}
	}
	if(data && max && rcvd)
	{
		fromlen = sizeof(mLastAddress);
		if((len=recvfrom(rcvSock, (char *)data, max, 0,
				(struct sockaddr *)&mLastAddress, &fromlen))>0)
		{
			if(len && ((mState == _cs_connected) &&
				(mLastAddress.sin_addr.s_addr != mRemoteAddress.sin_addr.s_addr)))
			{
				uchar *p = (uchar *)data;
		
				if(*channel == _pfc_Control)
				{
					if(*p++==_hpt_Setup)
						switch(*p++)
						{
							case _ptip_Call:
								// We are already connected.  Send back a busy notice.
								rdpkt[0] = _hpt_Setup;
								rdpkt[1] = _ptip_Busy;	rdlen = 2;
								WriteBlockTo(rdpkt, &rdlen, &mLastAddress);
								break;
							case _ptip_Probe:
								// We are already connected, but we don't report that to a probe.
								// The idea is that we only reveal our status if the other
								// party is also revealing its information.
								rdpkt[0] = _hpt_Setup;
								rdpkt[1] = _ptip_ProbeResponse;	rdlen = 2;
								if(gPGFOpts.popt.idUnencrypted && gPGFOpts.popt.idOutgoing &&
									gPGFOpts.popt.identity[0])
								{
									rdlen+= (rdpkt[2] = strlen(gPGFOpts.popt.identity)) + 1;
									strcpy(&rdpkt[3], gPGFOpts.popt.identity);
								}
								WriteBlockTo(rdpkt, &rdlen, &mLastAddress);
								break;
							case _ptip_Message:
								ReceiveUDPMsg(p, len -2);
								break;
						}
				}
				len = 0;
			}
		}
		else
			len = 0;
	}
	else
	{
		if((mState != _cs_connected) && (mState != _cs_connecting))
			Sleep(100);
	}
	if(err < 0)
	{
		err = WSAGetLastError();
		//pgp_errif(err);
	}
	return len;
}

void
CPFTInternet::ReceiveUDPMsg(uchar *msg, long len)
{
	//not implemented yet
}

PGErr
CPFTInternet::WriteBlockTo(void *buffer, long *count, struct sockaddr_in *addr)
{
	mTMutex->Wait(semaphore_WaitForever);
	// Send a datagram
	if(SOCKET_ERROR == sendto(mSocket, (char *)buffer, *count, 0,
		(struct sockaddr *)addr, sizeof(struct sockaddr_in)))
	{
		int err = WSAGetLastError();
		pgpAssertNoErr(err);
	}
	mTMutex->Signal();
	return 0;
}

PGErr
CPFTInternet::WriteBlock(void *buffer, long *count, short channel)
{
	return WriteBlockTo(buffer, count, &mRemoteAddress);
}

PGErr
CPFTInternet::WriteAsync(long count, short channel, AsyncTransport *async)
{
	int err;

	mTMutex->Wait(semaphore_WaitForever);
	// ###########################################
	// NEXT LINE OVERRIDES MULTIPLE UDP PORT USAGE
	// The support works fine for multiple ports, but 
	// since we chose not to use RTP, it seems best
	// to disable it for now to not clutter the ports
	// with packets that could just as easily be sent
	// on one port.
	channel = _pfc_Control;
	// Send a datagram
	switch(channel)
	{
		case _pfc_Control:
			err = sendto(mSocket, (char *)async->buffer, count, 0,
				(struct sockaddr *)&mRemoteAddress, sizeof(mRemoteAddress));
			break;
		case _pfc_Media:
			err = sendto(mMSocket, (char *)async->buffer, count, 0,
				(struct sockaddr *)&mMRemoteAddress, sizeof(mMRemoteAddress));
			break;
		case _pfc_MediaControl:
			err = sendto(mMCSocket, (char *)async->buffer, count, 0,
				(struct sockaddr *)&mMCRemoteAddress, sizeof(mMCRemoteAddress));
			break;
	}
	if(SOCKET_ERROR == err)
	{
		int err = WSAGetLastError();
		pgpAssertNoErr(err);
	}
	mTMutex->Signal();
	return 0;
}

void
CPFTInternet::CleanUp()
{
}

PGErr
CPFTInternet::BindMediaStreams()
{
	struct sockaddr_in localAddr;
	int err;

	mMSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
	mMCSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
	memset(&mMRemoteAddress, 0, sizeof(mMRemoteAddress));
	mMRemoteAddress.sin_family = PF_INET;
	mMRemoteAddress.sin_port = htons(RTPPORTNUMBER);
	mMRemoteAddress.sin_addr.s_addr = mRemoteAddress.sin_addr.s_addr;
	memset(&mMCRemoteAddress, 0, sizeof(mMCRemoteAddress));
	mMCRemoteAddress.sin_family = PF_INET;
	mMCRemoteAddress.sin_port = htons(RTCPPORTNUMBER);
	mMCRemoteAddress.sin_addr.s_addr = mRemoteAddress.sin_addr.s_addr;
	memset(&localAddr, 0, sizeof(localAddr));
	localAddr.sin_family = PF_INET;
	localAddr.sin_port = htons(RTPPORTNUMBER);
	err = bind(mMSocket, (struct sockaddr *)&localAddr, sizeof(localAddr));
	if(err)
	{
		err = WSAGetLastError();
		pgpAssertNoErr(err);
	}
	memset(&localAddr, 0, sizeof(localAddr));
	localAddr.sin_family = PF_INET;
	localAddr.sin_port = htons(RTCPPORTNUMBER);
	err = bind(mMCSocket, (struct sockaddr *)&localAddr, sizeof(localAddr));
	if(err)
	{
		err = WSAGetLastError();
		pgpAssertNoErr(err);
	}
	return err;
}

short
CPFTInternet::SleepForData(HANDLE *abortEvent)
{
	DWORD	result;

	//This code is not actually used.
	result = WaitForSingleObject(*abortEvent, INFINITE);
	if (result != WAIT_OBJECT_0)
		pgp_errstring("unknown error waiting for abort event");
	return 1;
}

⌨️ 快捷键说明

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