CClientSocket.Fetch

Newbie Spellweaver
Joined
Oct 11, 2024
Messages
72
Reaction score
16
Citer:
if( dwDataSize > MAX_BUFFER ) // if( uPacketSize > MAX_BUFFER ) // kang : 2008/08/14
{
char lpAddr[16] = { 0,} ;
GetPeerAddr( DPID_UNKNOWN, lpAddr, NULL ) ;
Error( « CClientSocket.Fetch : ip = %s, size = %d », lpAddr, dwDataSize ) ;
WSASetLastError( ERROR_BAD_NET_NAME ) ;
return NULL ;
}
Donc, le « MAX_BUFFER » est 8192 et vous essayez d’aller chercher 790647882.

Quelle source utilisez-vous ? il n’y a rien de mal avec le protocole net (NE TOUCHEZ JAMAIS À ÇA !!)

Il s’agit de paquets corrompus.

Problèmes possibles :

Cryptage des paquets (juste inutile..) mal implémenté,
Vous essayez d’envoyer des paquets corrompus.,
Quelqu’un a pris ses mains sur le tampon CAR (NE TOUCHEZ JAMAIS À ÇA AUSSI !!),

J’ai besoin de plus d’informations pour vous aider.

Ps. : Déboguer cela, regarder dans la pile.

  1. Est-ce que vous pouvez m’aider? Nous sommes prêts à payer.
 
Last edited:
i had this problem years ago, no one really gonna help you here with this problem for free anyways
 
Upvote 0
i had this problem years ago, no one really gonna help you here with this problem for free anyways
Hello, unfortunately you're probably right, the Flyff scene has become weird, I've noticed that since I came back. The mentality before was much better.
 
Upvote 0
Hello, unfortunately you're probably right, the Flyff scene has become weird, I've noticed that since I came back. The mentality before was much better.
Indeed it has changed a lot, it has nothing to do with before, it is a problem of packets received, but I have no idea all that could come there are many other solutions than installing the network code v21 code it says it on the other forum, good luck
 
Upvote 0
Quote:
if( dwDataSize > MAX_BUFFER ) // if( uPacketSize > MAX_BUFFER ) // kang: 2008/08/14
{
char lpAddr[16] = { 0,};
GetPeerAddr( DPID_UNKNOWN, lpAddr, NULL );
Error( "CClientSocket.Fetch: ip = %s, size = %d", lpAddr, dwDataSize );
WSASetLastError( ERROR_BAD_NET_NAME );
return NULL;
}
So the "MAX_BUFFER" is 8192 and you try to fetch 790647882.

What source do you use? there is nothing wrong with the net protocol (NEVER TOUCH THIS!!)

This are corrupted packets.

Possible problems:

Packet encryption (Just useless..) implemented wrong,
You try to send corrupted packets.,
Someone took his hands on the CAr buffer (NEVER TOUCH THIS TOO!!),

I need more information to help you.

Ps.: Debug that, look in stack.

  1. Can you help me? We are ready to pay.
You leaked your IP btw, If it's a VPS I suggest asking your hosting support to assign you another IP
 
Upvote 0
So the old network
in all these non-v21.2 sources

They're using an old 32-bit packet system. You can easily overflow with these packets these days because 99% of the network is 64-bit. Well, since we all have old sources, no one has ever updated the network. That's why the dosing happens. It's the overflow of a 64-bit packet sent to a 32-bit packet system. A 6 Gbps packet will overload it and crush it on 32, but with 64, it changes the dynamics of it.

But essentially anything below 21.2 is net 32-bit, 21.2 is net 64-bit. When you flood 32-bit with 64-bit packets, it overflows and creates crashes.

Any Layer 5-7 DDoS attack with a port throughput of 6 Gbps to the cache port will destroy them.
This is the infamous cache crash bug, and no one knows why.
21.2 net fixes this.

Or instead of using DP (DataPacket), change it to use Boost.Asio to modernize your server, improve asynchronous connection management, scalability and maintainability. but difficult to implement
 
Last edited:
Upvote 0
Donc, l’ancien réseau
Dans toutes ces sources non-v21.2

Ils utilisent un ancien système de paquets 32 bits. De nos jours, vous pouvez facilement déborder de ces paquets car 99 % du réseau est 64 bits. Eh bien, comme nous avons tous de vieilles sources, personne n’a jamais mis à jour le réseau. C’est pourquoi le dosage a lieu. Il s’agit du débordement d’un paquet de 64 bits envoyé à un système de paquets de 32 bits. Un paquet de 6 Gbps le surchargera et l’écrasera sur 32, mais avec 64, il en change la dynamique.

Mais essentiellement, tout ce qui est inférieur à 21,2 est net 32 bits, 21,2 est net 64 bits. Lorsque vous inondez 32 bits avec des paquets 64 bits, il déborde et crée des plantages.

Toute attaque DDoS de couche 5 à 7 avec un débit de port de 6 Gbit/s vers le port de cache les détruira.
Il s’agit du fameux bug de crash du cache, et personne ne sait pourquoi.
21.2 net résout ce problème.

Ou au lieu d’utiliser DP (DataPacket), changez-le pour utiliser Boost.Asio pour moderniser votre serveur, améliorer la gestion des connexions asynchrones, l’évolutivité et la maintenabilité. mais difficile à mettre en œuvreCi


Merci de ta réponse
 
Upvote 0
Hi, the secret fix for this is that only allow login, cache and account in your firewall the rest make sure its closed :P wola fixed
 
Upvote 0
Hello, unfortunately you're probably right, the Flyff scene has become weird, I've noticed that since I came back. The mentality before was much better.
This isn't exactly true atm. You are more likely to receive actual help now as the trolls and a-holes have left with that moldy condiment packet. :ROFLMAO:
 
Upvote 0
Hi, the secret fix for this is that only allow login, cache and account in your firewall the rest make sure its closed :P wola fixed
Really? Im not questioning your given methods. But this is reasons why my old server back then lost its population and reason I downed the server. I know for a fact that login, cache, and account is the only thing you need to open for ports. But this error overflowing packets is still happening, Crashing the worldserver.

I remember that I even changing the data that can possible to handle in vps server i forgot how I did it but something in device management.

But this was never the case.

This isn't exactly true atm. You are more likely to receive actual help now as the trolls and a-holes have left with that moldy condiment packet. :ROFLMAO:
Because people back then trying to be a d*ck when someone asking simple question. As if it is suppose to be a general knowledge. They shouldve not comment at all if they just gonna be d*ck about it
 
Upvote 0
You just need to open the ports in TCP in your firewall, and you won't have any crash issues, as Misterblue said, and you won't have any problems.
Just a little clarification, nothing else.

And check your INI files on the program side to ensure that all your ports are correctly configured.

_Networks\Msghdr.h :

#define PN_CERTIFIER 23000 // TO OPEN
#define PN_CACHESRVR 5400 // TO OPEN
#define PN_LOGINSRVR 28000 // TO OPEN
 
Last edited:
Upvote 0
Really? Im not questioning your given methods. But this is reasons why my old server back then lost its population and reason I downed the server. I know for a fact that login, cache, and account is the only thing you need to open for ports. But this error overflowing packets is still happening, Crashing the worldserver.

I remember that I even changing the data that can possible to handle in vps server i forgot how I did it but something in device management.

But this was never the case.


Because people back then trying to be a d*ck when someone asking simple question. As if it is suppose to be a general knowledge. They shouldve not comment at all if they just gonna be d*ck about it
At the time in 2010 when I had created my underworld-flyff server I didn’t have it’s problem the...
 
Upvote 0
Best thing to do is probably just use the updated network code as other users have suggested. It looks more clean and more resolved. Otherwiise...

There are a multitude of reasons why this could be happening because most of the network code looks and seems unsafe. For instance, a lot of the buffer code isn't safe when checking limits or sizes so you're able to get some weird results if some things happen.

I believe it's more so a small spoof than a massive packet. A user or server still needs to emit that data to the server or partial of it, which is more likely than someone trying to upload 6gb of data over the tcp connection or some mismatch occuring.

This could be due to the CRC code is only enabled in some of the servers and not all, even though CRC isn't used in most of the servers, but who knows.

Code:
		if( &pClientSock->m_ovRecv == lpov )	// receive i/o completed
		{
			CBuffer* pBuffer	= pClientSock->Fetch( dwBytes );
			if( pBuffer )
			{
				if( pBuffer->cb > 0 ) {
#ifdef __PROTOCOL0910
					if( pClientSock->IsCrcWrite() && pClientSock->m_dwProtocolId == 0 )
					{
						LPBYTE ptr	= pBuffer->m_lpBufStart;
						if( *(UNALIGNED LPDWORD)( ptr + pDPSock->m_dwDataSizeOffset ) == 8 )
						{
							if (*(UNALIGNED LPDWORD)(&ptr[pDPSock->m_dwReadHeaderSize]) == 0x00000000)
								pDPSock->SetProtocolId( *(UNALIGNED LPDWORD)( &ptr[pDPSock->m_dwReadHeaderSize + 4] ) );
						}
					}
#endif
					pBuffer->dpid	= hSocket;
					pDPSock->m_lspRecvBuffer.AddTail( pBuffer );
					SetEvent( pDPSock->GetRecvHandle() );
				}
				else 
					SAFE_DELETE( pBuffer );
			}
			else if( WSAGetLastError() ==  ERROR_BAD_NET_NAME )
			{
				pDPSock->CloseConnection( hSocket );
				continue;
			}

			if( pClientSock->Recv() != 0 )	// i/o error
			{
				pClientSock->m_AccessLock.Enter();
				pClientSock->m_bDoNotWrite	= TRUE;
				int nReference	= --pClientSock->m_nReference;
				pClientSock->m_AccessLock.Leave();
				if( nReference == 0 )
					pDPSock->CloseConnection( hSocket );
			}
		}

If the receive handle is triggered within the IoWorkerThread, fetch is ran with the expected bytes sent.

And within that function, it tries to increase the m_pTail pointer by the bytes sent, and then it grabs the readablebuffer.

C++:
	m_pRecvBuffer->m_pTail	+=	dwBytes;

	int nRemnant;
	LPBYTE ptr	= m_pRecvBuffer->GetReadableBuffer( &nRemnant );

Well, what if m_pTail > m_lpBuffMax after the add to dwBytes. You'd be traversing unowned memory, which is UB, generally an access violation. Checking If the writable size allows the tail to be written, then that helps.
C++:
	if (m_pRecvBuffer->GetWritableBufferSize() >= dwBytes)
		m_pRecvBuffer->m_pTail	+=	dwBytes;

Then the that function itself, also doesn't validate if the tail was already overflown. This is probably less likely a cause in this case.
C++:
inline int CBuffer::GetWritableBufferSize( void )
{	
	if (m_pTail > m_lpBufMax) // Validation
		return 0;

	return (int)( m_lpBufMax - m_pTail );	
}

The same issue can persist within the other function, GetReadableBuffer and GetReadableBufferSize
C++:
inline LPBYTE CBuffer::GetReadableBuffer( int* pnBufSize )
{	
	*pnBufSize	= GetReadableBufferSize(); // might as well call the other inline function below to get the size and set it to the pointer passed through.	
	return m_pHead;	
}

inline int CBuffer::GetReadableBufferSize( void )
{	
	if (m_pHead > m_pTail) // validation
		return 0;

	return (int)( m_pTail - m_pHead );	
}

---

Within the loop itself, there are a few things that happens. If the remaining data size is less than the header size, that means that the packet is incomplete, there's no header information to peak in to.

C++:
#ifdef __CRC
		if( nRemnant < (int)( m_dwReadHeaderSize ) )
#else	// __CRC
		if( nRemnant < (int)( m_pRecvBuffer->GetHeaderLength() ) )
#endif	// __CRC
		{
			if( m_pRecvBuffer->cb > 0 ) 
			{
				pOld	= m_pRecvBuffer;
				pOld->m_pTail	-= nRemnant;	// remove remnant from old buffer
				m_pRecvBuffer	= CBufferFactory::GetInstance().CreateBuffer( m_nBufferType );
#ifdef __SO1014
				if( !m_pRecvBuffer->m_lpBufStart )
				{
					WriteError( "FETCH//2" );
					WSASetLastError( ERROR_BAD_NET_NAME );
					return NULL;
				}
#endif	// __SO1014
				memcpy( m_pRecvBuffer->m_pTail, ptr, nRemnant );

				m_pRecvBuffer->m_pTail	+=	nRemnant;
			}
			return pOld;
		}

I assume cb is short for "current blocks". Meaning, if there is more blocks to be read, we need to do something to the remnant data so we are able to parse the remnant data with the new data. So, in this case, it stores the m_pRecvBuffer point in pOld, then subtracts the remaining size from that buffer. This is to not overread from the old buffer. The buffer Factory then generates another buffer (from the type which isn't used unless you're utilizing dpbilling and adbil for CBuffer2). It checks to see if the internal buffer was created from the malloc call within the SO1014 call then it copies that data to the new buffer's tail.

This should be safe as nRemnant is smaller than the header sizes, so having to validate the copy when the CBuffer object gets allocated with a size of 8192, and you shouldn't have to change the m_pTail += nRemnant in this code block either because of that -- the writable size should be properly done. Then it returns the old buffer.

The next section of the code, checks for the size (and this is where you experience a crash). Servers that are using CRC, expects a different size header because of the extra information transferred (crc). So, it uses an offset, casting and pointer dereferencing to convert to the expected variables. Ideally, and I noticed this from a quick look at the newer net code, they converted this to a struct and sizeof(struct) for cleaner visibility.

Another thing missing is Header Mark validation and whenver 'BadNetName" is called the connection will close from:
C++:
	else if( WSAGetLastError() ==  ERROR_BAD_NET_NAME )
	{
		pDPSock->CloseConnection( hSocket );
		continue;
	}
And looking at the newer network code, it seems like the removed the calls to this.

You could try the following:
C++:
	while( 1 )
	{
		VERIFY_LOOP( __FILE__, __LINE__ );
#ifdef __CRC
		if( nRemnant < (int)( m_dwReadHeaderSize ) )
#else	// __CRC
		if( nRemnant < (int)( m_pRecvBuffer->GetHeaderLength() ) )
#endif	// __CRC
		{
			if( m_pRecvBuffer->cb > 0 ) 
			{
				pOld	= m_pRecvBuffer;
				pOld->m_pTail	-= nRemnant;	// remove remnant from old buffer
				m_pRecvBuffer	= CBufferFactory::GetInstance().CreateBuffer( m_nBufferType );
#ifdef __SO1014
				if( !m_pRecvBuffer->m_lpBufStart )
				{
					WriteError( "FETCH//2" );
					return nullptr;
				}
#endif
				memcpy( m_pRecvBuffer->m_pTail, ptr, nRemnant );
				m_pRecvBuffer->m_pTail	+=	nRemnant;
			}
			return pOld;
		}

		// Check for header mark before moving the offset
		if (*ptr != HEADERMARK)
		{
			WriteError("Invalid HeaderMark.");
			return nullptr;
		}

		int nOffset = sizeof(char); // skips first character
#ifdef __CRC
		if (m_dwReadHeaderSize == HEADERSIZE13)
		{
			// reads unigned long and adds the size of unsigned long to offset
			// This crc value is for the datasize.
			dwCrc = *(UNALIGNED LPDWORD)(ptr + nOffset);
			nOffset += sizeof(DWORD);

			// reads unigned long and adds the size of unsigned long to offset
			dwDataSize = *(UNALIGNED LPDWORD)(ptr + nOffset);
			nOffset += sizeof(DWORD);

			// starts the crc engine
			m_crcRead.Restart();
			m_crcRead.Update((const byte*)(&dwDataSize), sizeof(DWORD));
			m_crcRead.Final(digest);

			// converts the size and uses the digest to check the protocol id.
			if (~(*(UNALIGNED LPDWORD)digest ^ m_dwProtocolId) != dwCrc)
				return nullptr;

			// Grabs another unsigned long (another crc value) replacing the old one.and pushes the offset to the end of the header.
			dwCrc = *(UNALIGNED LPDWORD)(ptr + nOffset);
			nOffset += sizeof(DWORD);

			// The packet sizs itself is the total DataSize and the HeaderSize
			uPacketSize = m_dwReadHeaderSize + dwDataSize;

			// if the data size is larger than the maximum buffer.
			if (dwDataSize > MAX_BUFFER)	// if( uPacketSize > MAX_BUFFER )	// kang: 2008/08/14
			{
				char lpAddr[16] = { 0, };
				GetPeerAddr(DPID_UNKNOWN, lpAddr, NULL);
				Error("CClientSocket.Fetch: ip = %s, size = %d", lpAddr, dwDataSize);
				return nullptr;
			}
		}
		else
		{
			// If it isn't the crc Header, the packet size variable is equal to the header size and the unsigned long after the header mark in the data.
			uPacketSize = m_dwReadHeaderSize + *(UNALIGNED LPDWORD)(ptr + nOffset);
		}
#else	// __CRC
		// And if crc is disabled on the server, it runs the functions where you crash on one.
		uPacketSize = m_pRecvBuffer->GetHeaderLength() + m_pRecvBuffer->GetPacketSize(ptr); // *(UNALIGNED LPDWORD)(ptr + nOffset) is the same in this case here.
#endif	// __CRC

		// if the remaining writable data is less the packet size
		if (nRemnant < (int)(uPacketSize))
		{

			// and if the packet size is greater than the recieve buffer size or if the current blocks within the buffer is more than 0 (GetSize should be safe because it always checks the size of the allocated internal buffer by checking the max (end pointer) subtracted by the start (starting pointer)
			if ((int)(uPacketSize) > m_pRecvBuffer->GetSize() || m_pRecvBuffer->cb > 0)
			{
				pOld = m_pRecvBuffer;

				// Tries to allocate the Exact packet size rather than 8192
				m_pRecvBuffer = CBufferFactory::GetInstance().CreateBuffer(m_nBufferType, uPacketSize);
				if (!m_pRecvBuffer->m_lpBufStart)
				{
					char lpAddr[16] = { 0, };
					GetPeerAddr(DPID_UNKNOWN, lpAddr, NULL);
					Error("CClientSocket.Fetch: ip = %s, size = %d", lpAddr, uPacketSize);
					return NULL;
				}
			}

			// If pOld got set from above and is VALID.
			if (pOld)
			{
				if (!m_pRecvBuffer->m_lpBufStart)
				{
					WriteError("FETCH//3");
					WSASetLastError(ERROR_BAD_NET_NAME);
					return NULL;
				}

				// it than adds the remant to the new buffer. I don't know the name of this style but it's just moving pieces around to new buffers whihc should be safe, but if not, there's always stuff in the newer network code like validating if the size and nRemnant could be written here to the tail.
				memcpy(m_pRecvBuffer->m_pTail, ptr, nRemnant);
				m_pRecvBuffer->m_pTail += nRemnant;
			}
			return pOld;
		}
#ifdef __CRC
		// if crc is enabled, check the header size for the crc header
		if (m_dwReadHeaderSize == HEADERSIZE13)
		{
			m_crcRead.Restart();
			m_crcRead.Update((const byte*)(ptr + m_dwReadHeaderSize), dwDataSize);
			m_crcRead.Final(digest);
			// Pass the data in the the crc and then validate the crc with the protocol
			if (~(*(UNALIGNED LPDWORD)digest ^ m_dwProtocolId) != dwCrc)
			{
				char lpAddr[16] = { 0, };
				GetPeerAddr(DPID_UNKNOWN, lpAddr, NULL);
				Error("CClientSock.Fetch: replay: %s", lpAddr);
				WSASetLastError(ERROR_BAD_NET_NAME);
				return NULL;
			}
		}
#endif	// __CRC
		// Received data, increase the currently block
		m_pRecvBuffer->cb++;
		// decrease the packetsize from the writable size
		nRemnant -= (uPacketSize);
		// offset the pointer
		ptr += (uPacketSize);
	}
	return nullptr;

Note: You could just try applying the buffer and bufferqueue changes where they appear and see if that helps as well. I'll continue with a deep dive of the network code at another time if it still happens, but PLEASE provide more details. Show more of the stack trace, and what the objects are set from the auto window, etc.
 
Upvote 0
Back