Example #1
0
// 次のパケットを取得
UINT LinkPaGetNextPacket(SESSION *s, void **data)
{
	LINK *k;
	UINT ret = 0;
	// 引数チェック
	if (s == NULL || data == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL)
	{
		return INFINITE;
	}

	// キューにパケットが溜まっているかどうか調べる
	LockQueue(k->SendPacketQueue);
	{
		BLOCK *block = GetNext(k->SendPacketQueue);

		if (block != NULL)
		{
			// パケットがあった
			*data = block->Buf;
			ret = block->Size;
			// 構造体のメモリは破棄する
			Free(block);
		}
	}
	UnlockQueue(k->SendPacketQueue);

	return ret;
}
Example #2
0
// Release the packet adapter
void LinkPaFree(SESSION *s)
{
	LINK *k;
	// Validate arguments
	if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL)
	{
		return;
	}

	// Stop the server session
	StopSession(k->ServerSession);
	ReleaseSession(k->ServerSession);

	// Release the transmission packet queue
	LockQueue(k->SendPacketQueue);
	{
		BLOCK *block;
		while (block = GetNext(k->SendPacketQueue))
		{
			FreeBlock(block);
		}
	}
	UnlockQueue(k->SendPacketQueue);

	ReleaseQueue(k->SendPacketQueue);
}
UINT EthGetPacketBpf(ETH *e, void **data)
{
	struct CAPTUREBLOCK *block;
	UINT size;
	
	LockQueue(e->Queue);
	block = GetNext(e->Queue);
	if(block != NULL){
		e->QueueSize -= block->Size;
	}
	UnlockQueue(e->Queue);
	
	if(block == NULL){
		*data = NULL;
		if(e->Socket == INVALID_SOCKET){
			return INFINITE;
		}
		return 0;
	}
	
	*data = block->Buf;
	size = block->Size;
	FreeCaptureBlock(block);
	
	return size;
}
Example #4
0
// Packet generation thread
void NullPacketGenerateThread(THREAD *t, void *param)
{
	NULL_LAN *n = (NULL_LAN *)param;
	// Validate arguments
	if (t == NULL || param == NULL)
	{
		return;
	}

	while (true)
	{
		Wait(n->Event, Rand32() % NULL_PACKET_GENERATE_INTERVAL);
		if (n->Halt)
		{
			break;
		}

		LockQueue(n->PacketQueue);
		{
			UCHAR *data;
			BLOCK *b;
			UINT size = Rand32() % 1500 + 14;
			data = Malloc(size);
			Copy(data, null_lan_broadcast_address, 6);
			Copy(data + 6, n->MacAddr, 6);
			b = NewBlock(data, size, 0);
			InsertQueue(n->PacketQueue, b);
		}
		UnlockQueue(n->PacketQueue);
		Cancel(n->Cancel);
	}
}
Example #5
0
// パケットアダプタの解放
void LinkPaFree(SESSION *s)
{
	LINK *k;
	// 引数チェック
	if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL)
	{
		return;
	}

	// サーバーセッションの停止
	StopSession(k->ServerSession);
	ReleaseSession(k->ServerSession);

	// 送信パケットキューの解放
	LockQueue(k->SendPacketQueue);
	{
		BLOCK *block;
		while (block = GetNext(k->SendPacketQueue))
		{
			FreeBlock(block);
		}
	}
	UnlockQueue(k->SendPacketQueue);

	ReleaseQueue(k->SendPacketQueue);
}
Example #6
0
// Get the next packet
UINT NullPaGetNextPacket(SESSION *s, void **data)
{
	UINT size = 0;
	// Validate arguments
	NULL_LAN *n;
	if (s == NULL || (n = s->PacketAdapter->Param) == NULL)
	{
		return INFINITE;
	}

	LockQueue(n->PacketQueue);
	{
		BLOCK *b = GetNext(n->PacketQueue);

		if (b != NULL)
		{
			*data = b->Buf;
			size = b->Size;
			Free(b);
		}
	}
	UnlockQueue(n->PacketQueue);

	return size;
}
Example #7
0
// Release the packet adapter
void LinkPaFree(SESSION *s)
{
	LINK *k;
	// Validate arguments
	if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL)
	{
		return;
	}

	CedarAddQueueBudget(k->Cedar, -((int)k->LastServerConnectionReceivedBlocksNum));
	k->LastServerConnectionReceivedBlocksNum = 0;

	// Stop the server session
	StopSession(k->ServerSession);
	ReleaseSession(k->ServerSession);

	// Release the transmission packet queue
	LockQueue(k->SendPacketQueue);
	{
		BLOCK *block;
		while (block = GetNext(k->SendPacketQueue))
		{
			FreeBlock(block);
		}
	}
	UnlockQueue(k->SendPacketQueue);

	ReleaseQueue(k->SendPacketQueue);

	k->CurrentSendPacketQueueSize = 0;
}
Example #8
0
// Release
void NullPaFree(SESSION *s)
{
	// Validate arguments
	NULL_LAN *n;
	BLOCK *b;
	if (s == NULL || (n = s->PacketAdapter->Param) == NULL)
	{
		return;
	}

	n->Halt = true;
	Set(n->Event);

	WaitThread(n->PacketGeneratorThread, INFINITE);
	ReleaseThread(n->PacketGeneratorThread);

	LockQueue(n->PacketQueue);
	{
		while (b = GetNext(n->PacketQueue))
		{
			FreeBlock(b);
		}
	}
	UnlockQueue(n->PacketQueue);

	ReleaseQueue(n->PacketQueue);

	ReleaseCancel(n->Cancel);

	ReleaseEvent(n->Event);

	s->PacketAdapter->Param = NULL;
	Free(n);
}
Example #9
0
// Get the next packet
UINT LinkPaGetNextPacket(SESSION *s, void **data)
{
	LINK *k;
	UINT ret = 0;
	// Validate arguments
	if (s == NULL || data == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL)
	{
		return INFINITE;
	}

	// Examine whether there are packets in the queue
	LockQueue(k->SendPacketQueue);
	{
		BLOCK *block = GetNext(k->SendPacketQueue);

		if (block != NULL)
		{
			// There was a packet
			*data = block->Buf;
			ret = block->Size;
			// Discard the memory for the structure
			Free(block);
		}
	}
	UnlockQueue(k->SendPacketQueue);

	return ret;
}
Example #10
0
static int RemoveLast()
{
  SrvJob *job;
  int status;
  LockQueue();
  job = LastQueueEntry;
  if (job)
  {
    LastQueueEntry = job->h.previous;
    if(LastQueueEntry) 
      LastQueueEntry->h.next = 0;
    else 
      FirstQueueEntry = 0;

    FreeJob(job);
    printf("Removed pending action");
    status = 1;
  }
  else
  {
    status = 0;
  }
  UnlockQueue();
  return status;
}
Example #11
0
// Relay thread for captured packet (BPF)
void BpfThread(THREAD *thread, void *param)
{
	ETH *e = (ETH*)param;
	int fd = e->Socket;
	int len;
	int rest;	// Rest size in buffer
	UCHAR *next;	// Head of next packet in buffer
	struct CAPTUREBLOCK *block;	// Data to enqueue
	UCHAR *data;
	struct bpf_hdr *hdr;

	// Allocate the buffer
	UCHAR *buf = Malloc(e->BufSize);
	
	// Notify initialize completed
	NoticeThreadInit(thread);

	while(1){
		// Determining to exit loop
		if(e->Socket == INVALID_SOCKET){
			break;
		}
		
		rest = read(fd, buf, e->BufSize);
		if(rest < 0 && errno != EAGAIN){
			// Error
			close(fd);
			e->Socket = INVALID_SOCKET;
			Free(buf);
			Cancel(e->Cancel);
			return;
		}
		next = buf;
		LockQueue(e->Queue);
		while(rest>0){
			// Cut out a packet
			hdr = (struct bpf_hdr*)next;

			// Discard arriving packet when queue filled
			if(e->QueueSize < BRIDGE_MAX_QUEUE_SIZE){
				data = Malloc(hdr->bh_caplen);
				Copy(data, next+(hdr->bh_hdrlen), hdr->bh_caplen);
				block = NewCaptureBlock(data, hdr->bh_caplen);
				InsertQueue(e->Queue, block);
				e->QueueSize += hdr->bh_caplen;
			}

			// Find the head of next packet
			rest -= BPF_WORDALIGN(hdr->bh_hdrlen + hdr->bh_caplen);
			next += BPF_WORDALIGN(hdr->bh_hdrlen + hdr->bh_caplen);
		}
		UnlockQueue(e->Queue);
		Cancel(e->Cancel);
	}
	Free(buf);
	Cancel(e->Cancel);
	return;
}
Example #12
0
// BPF でのパケットキャプチャの中継用スレッド
void BpfThread(THREAD *thread, void *param)
{
	ETH *e = (ETH*)param;
	int fd = e->Socket;
	int len;
	int rest;	// バッファ中の残りバイト数
	UCHAR *next;	//バッファ中の次のパケットの先頭
	struct CAPTUREBLOCK *block;	// キューに追加するデータ
	UCHAR *data;
	struct bpf_hdr *hdr;

	// バッファを確保
	UCHAR *buf = Malloc(e->BufSize);
	
	// 初期化完了を通知
	NoticeThreadInit(thread);

	while(1){
		// ループの脱出判定
		if(e->Socket == INVALID_SOCKET){
			break;
		}
		
		rest = read(fd, buf, e->BufSize);
		if(rest < 0 && errno != EAGAIN){
			// エラー
			close(fd);
			e->Socket = INVALID_SOCKET;
			Free(buf);
			Cancel(e->Cancel);
			return;
		}
		next = buf;
		LockQueue(e->Queue);
		while(rest>0){
			// パケットの切り出し
			hdr = (struct bpf_hdr*)next;

			// Queue中のパケットサイズが限界を超えたらパケットを破棄する
			if(e->QueueSize < BRIDGE_MAX_QUEUE_SIZE){
				data = Malloc(hdr->bh_caplen);
				Copy(data, next+(hdr->bh_hdrlen), hdr->bh_caplen);
				block = NewCaptureBlock(data, hdr->bh_caplen);
				InsertQueue(e->Queue, block);
				e->QueueSize += hdr->bh_caplen;
			}

			// 次のパケットの頭出し
			rest -= BPF_WORDALIGN(hdr->bh_hdrlen + hdr->bh_caplen);
			next += BPF_WORDALIGN(hdr->bh_hdrlen + hdr->bh_caplen);
		}
		UnlockQueue(e->Queue);
		Cancel(e->Cancel);
	}
	Free(buf);
	Cancel(e->Cancel);
	return;
}
Example #13
0
// Packet generation thread
void NullPacketGenerateThread(THREAD *t, void *param)
{
	NULL_LAN *n = (NULL_LAN *)param;
	UINT64 end_tick = Tick64() + (UINT64)(60 * 1000);
	UINT seq = 0;
	// Validate arguments
	if (t == NULL || param == NULL)
	{
		return;
	}

	while (true)
	{
		/*if (Tick64() >= end_tick)
		{
			break;
		}*/

		Wait(n->Event, Rand32() % 1500);
		if (n->Halt)
		{
			break;
		}

		LockQueue(n->PacketQueue);
		{
			UCHAR *data;
			BLOCK *b;
			UINT size = Rand32() % 1500 + 14;
			UCHAR dst_mac[6];

			NullGenerateMacAddress(n->MacAddr, n->Id, seq);

			//NullGenerateMacAddress(dst_mac, n->Id + 1, 0);
			//StrToMac(dst_mac, "00-1B-21-A9-47-E6");
			StrToMac(dst_mac, "00-AC-7A-EF-83-FD");

			data = Malloc(size);
			Copy(data, null_lan_broadcast_address, 6);
			//Copy(data, dst_mac, 6);
			Copy(data + 6, n->MacAddr, 6);
			b = NewBlock(data, size, 0);
			InsertQueue(n->PacketQueue, b);
		}
		UnlockQueue(n->PacketQueue);
		Cancel(n->Cancel);

		//seq++;
	}
}
Example #14
0
static int QJob(SrvJob *job)
{
  SrvJob *qjob = (SrvJob *)memcpy(malloc(job->h.length),job,job->h.length);
  LockQueue();
  if (LastQueueEntry != 0)
    LastQueueEntry->h.next = qjob;
  qjob->h.next = 0;
  qjob->h.previous = LastQueueEntry;
  LastQueueEntry = qjob;
  if (FirstQueueEntry == 0)
    FirstQueueEntry = qjob;
  UnlockQueue();
  return StartThread();
}
Example #15
0
bool Frontend::ServerEditQueue(DownloadQueue::EEditAction eAction, int iOffset, int iID)
{
	if (IsRemoteMode())
	{
		return RequestEditQueue(eAction, iOffset, iID);
	}
	else
	{
		DownloadQueue* pDownloadQueue = LockQueue();
		bool bOK = pDownloadQueue->EditEntry(iID, eAction, iOffset, NULL);
		UnlockQueue();
		return bOK;
	}
	return false;
}
Example #16
0
static SrvJob *LastJob()
{
  SrvJob *job;
  LockQueue();
  job = LastQueueEntry;
  if (job)
  {
    LastQueueEntry = job->h.previous;
    if(LastQueueEntry) 
      LastQueueEntry->h.next = 0;
    else 
      FirstQueueEntry = 0;
  }
  UnlockQueue();
  return job;
}
Example #17
0
// パケット到着のコールバック関数
void PcapHandler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
{
	ETH *e = (ETH*) user;
	struct CAPTUREBLOCK *block;
	UCHAR *data;
	
	data = Malloc(h->caplen);
	Copy(data, bytes, h->caplen);
	block = NewCaptureBlock(data, h->caplen);
	LockQueue(e->Queue);
	// キューのサイズが限界を超えたらパケットを破棄する。
	if(e->QueueSize < BRIDGE_MAX_QUEUE_SIZE){
		InsertQueue(e->Queue, block);
		e->QueueSize += h->caplen;
	}
	UnlockQueue(e->Queue);
	Cancel(e->Cancel);
	return;
}
Example #18
0
// Callback function to receive arriving packet (Pcap)
void PcapHandler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
{
	ETH *e = (ETH*) user;
	struct CAPTUREBLOCK *block;
	UCHAR *data;
	
	data = Malloc(h->caplen);
	Copy(data, bytes, h->caplen);
	block = NewCaptureBlock(data, h->caplen);
	LockQueue(e->Queue);
	// Discard arriving packet when queue filled
	if(e->QueueSize < BRIDGE_MAX_QUEUE_SIZE){
		InsertQueue(e->Queue, block);
		e->QueueSize += h->caplen;
	}
	UnlockQueue(e->Queue);
	Cancel(e->Cancel);
	return;
}
Example #19
0
// 受信したパケットを書き込み
bool LinkPaPutPacket(SESSION *s, void *data, UINT size)
{
	LINK *k;
	BLOCK *block;
	SESSION *server_session;
	CONNECTION *server_connection;
	// 引数チェック
	if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL)
	{
		return false;
	}

	server_session = k->ServerSession;
	server_connection = server_session->Connection;

	// ここにはリンク接続先の HUB から届いたパケットが来るので
	// サーバーセッションの ReceivedBlocks に届けてあげる
	if (data != NULL)
	{
		block = NewBlock(data, size, 0);

		LockQueue(server_connection->ReceivedBlocks);
		{
			InsertQueue(server_connection->ReceivedBlocks, block);
		}
		UnlockQueue(server_connection->ReceivedBlocks);
	}
	else
	{
		// data == NULL のとき、すべてのパケットを格納し終わったので
		// Cancel を発行する
		Cancel(server_session->Cancel1);

		if (k->Hub != NULL && k->Hub->Option != NULL && k->Hub->Option->YieldAfterStorePacket)
		{
			YieldCpu();
		}
	}

	return true;
}
Example #20
0
// Get the next packet
UINT L3GetNextPacket(L3IF *f, void **data)
{
	UINT ret = 0;
	// Validate arguments
	if (f == NULL || data == NULL)
	{
		return 0;
	}

START:
	// Examine the send queue
	LockQueue(f->SendQueue);
	{
		PKT *p = GetNext(f->SendQueue);

		if (p != NULL)
		{
			// There is a packet
			ret = p->PacketSize;
			*data = p->PacketData;
			// Packet structure may be discarded
			Free(p);
		}
	}
	UnlockQueue(f->SendQueue);

	if (ret == 0)
	{
		// Polling process
		L3Polling(f);

        // Examine whether a new packet is queued for results of the polling process
		if (f->SendQueue->num_item != 0)
		{
			// Get the packet immediately if it's in the queue
			goto START;
		}
	}

	return ret;
}
Example #21
0
// Write the received packet
bool LinkPaPutPacket(SESSION *s, void *data, UINT size)
{
	LINK *k;
	BLOCK *block;
	SESSION *server_session;
	CONNECTION *server_connection;
	// Validate arguments
	if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL)
	{
		return false;
	}

	server_session = k->ServerSession;
	server_connection = server_session->Connection;

	// Since the packet arrives from the HUB of the link destination,
	// deliver it to the ReceivedBlocks of the server session
	if (data != NULL)
	{
		block = NewBlock(data, size, 0);

		LockQueue(server_connection->ReceivedBlocks);
		{
			InsertQueue(server_connection->ReceivedBlocks, block);
		}
		UnlockQueue(server_connection->ReceivedBlocks);
	}
	else
	{
		// Issue the Cancel, since finished store all packets when the data == NULL
		Cancel(server_session->Cancel1);

		if (k->Hub != NULL && k->Hub->Option != NULL && k->Hub->Option->YieldAfterStorePacket)
		{
			YieldCpu();
		}
	}

	return true;
}
Example #22
0
static SrvJob *NextJob(int wait)
{
  SrvJob *job;
  int done = 0;
  while (!done)
  {
    LockQueue();
    job = FirstQueueEntry;
    if (job)
    {
      FirstQueueEntry = job->h.next;
      if (FirstQueueEntry != 0)
        FirstQueueEntry->h.previous = 0;
      else
        LastQueueEntry = 0;
    }
    UnlockQueue();
    if (job || (!wait))
      done = 1;
    else
      WaitForJob();
  }
  return job;
}
Example #23
0
// Write the received packet
bool LinkPaPutPacket(SESSION *s, void *data, UINT size)
{
	LINK *k;
	BLOCK *block = NULL;
	SESSION *server_session;
	CONNECTION *server_connection;
	bool ret = true;
	bool halting = false;
	// Validate arguments
	if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL)
	{
		return false;
	}

	halting = (k->Halting || (*k->StopAllLinkFlag));

	server_session = k->ServerSession;
	server_connection = server_session->Connection;

	k->Flag1++;
	if ((k->Flag1 % 32) == 0)
	{
		// Ommit for performance
		UINT current_num;
		int diff;

		current_num = GetQueueNum(server_connection->ReceivedBlocks);

		diff = (int)current_num - (int)k->LastServerConnectionReceivedBlocksNum;

		k->LastServerConnectionReceivedBlocksNum = current_num;

		CedarAddQueueBudget(k->Cedar, diff);
	}

	// Since the packet arrives from the HUB of the link destination,
	// deliver it to the ReceivedBlocks of the server session
	if (data != NULL)
	{
		if (halting == false)
		{
			block = NewBlock(data, size, 0);
		}

		if (k->LockFlag == false)
		{
			UINT current_num;
			int diff;

			k->LockFlag = true;
			LockQueue(server_connection->ReceivedBlocks);

			current_num = GetQueueNum(server_connection->ReceivedBlocks);

			diff = (int)current_num - (int)k->LastServerConnectionReceivedBlocksNum;

			k->LastServerConnectionReceivedBlocksNum = current_num;

			CedarAddQueueBudget(k->Cedar, diff);
		}

		if (halting == false)
		{
			if (CedarGetFifoBudgetBalance(k->Cedar) == 0)
			{
				FreeBlock(block);
			}
			else
			{
				InsertReveicedBlockToQueue(server_connection, block, true);
			}
		}
	}
	else
	{
		UINT current_num;
		int diff;

		current_num = GetQueueNum(server_connection->ReceivedBlocks);

		diff = (int)current_num - (int)k->LastServerConnectionReceivedBlocksNum;

		k->LastServerConnectionReceivedBlocksNum = current_num;

		CedarAddQueueBudget(k->Cedar, diff);

		if (k->LockFlag)
		{
			k->LockFlag = false;
			UnlockQueue(server_connection->ReceivedBlocks);
		}

		// Issue the Cancel, since finished store all packets when the data == NULL
		Cancel(server_session->Cancel1);

		if (k->Hub != NULL && k->Hub->Option != NULL && k->Hub->Option->YieldAfterStorePacket)
		{
			YieldCpu();
		}
	}

	if (halting)
	{
		ret = false;
	}

	return ret;
}
Example #24
0
static void ReleaseCurrentJob()
{
  UnlockQueue();
}
Example #25
0
static void SetCurrentJob(SrvJob *job)
{
  LockQueue();
  CurrentJob = job;
  UnlockQueue();
}
Example #26
0
bool Frontend::RequestFileList()
{
	const char* szControlIP = !strcmp(g_pOptions->GetControlIP(), "0.0.0.0") ? "127.0.0.1" : g_pOptions->GetControlIP();
	Connection connection(szControlIP, g_pOptions->GetControlPort(), false);

	bool OK = connection.Connect();
	if (!OK)
	{
		return false;
	}

	SNZBListRequest ListRequest;
	InitMessageBase(&ListRequest.m_MessageBase, eRemoteRequestList, sizeof(ListRequest));
	ListRequest.m_bFileList = htonl(m_bFileList);
	ListRequest.m_bServerState = htonl(m_bSummary);

	if (!connection.Send((char*)(&ListRequest), sizeof(ListRequest)))
	{
		return false;
	}

	// Now listen for the returned list
	SNZBListResponse ListResponse;
	bool bRead = connection.Recv((char*) &ListResponse, sizeof(ListResponse));
	if (!bRead || 
		(int)ntohl(ListResponse.m_MessageBase.m_iSignature) != (int)NZBMESSAGE_SIGNATURE ||
		ntohl(ListResponse.m_MessageBase.m_iStructSize) != sizeof(ListResponse))
	{
		return false;
	}

	char* pBuf = NULL;
	if (ntohl(ListResponse.m_iTrailingDataLength) > 0)
	{
		pBuf = (char*)malloc(ntohl(ListResponse.m_iTrailingDataLength));
		if (!connection.Recv(pBuf, ntohl(ListResponse.m_iTrailingDataLength)))
		{
			free(pBuf);
			return false;
		}
	}

	connection.Disconnect();

	if (m_bSummary)
	{
		m_bPauseDownload = ntohl(ListResponse.m_bDownloadPaused);
		m_lRemainingSize = Util::JoinInt64(ntohl(ListResponse.m_iRemainingSizeHi), ntohl(ListResponse.m_iRemainingSizeLo));
		m_iCurrentDownloadSpeed = ntohl(ListResponse.m_iDownloadRate);
		m_iDownloadLimit = ntohl(ListResponse.m_iDownloadLimit);
		m_iThreadCount = ntohl(ListResponse.m_iThreadCount);
		m_iPostJobCount = ntohl(ListResponse.m_iPostJobCount);
		m_iUpTimeSec = ntohl(ListResponse.m_iUpTimeSec);
		m_iDnTimeSec = ntohl(ListResponse.m_iDownloadTimeSec);
		m_bStandBy = ntohl(ListResponse.m_bDownloadStandBy);
		m_iAllBytes = Util::JoinInt64(ntohl(ListResponse.m_iDownloadedBytesHi), ntohl(ListResponse.m_iDownloadedBytesLo));
	}

	if (m_bFileList && ntohl(ListResponse.m_iTrailingDataLength) > 0)
	{
		RemoteClient client;
		client.SetVerbose(false);
		
		DownloadQueue* pDownloadQueue = LockQueue();
		client.BuildFileList(&ListResponse, pBuf, pDownloadQueue);
		UnlockQueue();
	}

	if (pBuf)
	{
		free(pBuf);
	}

	return true;
}