Advertisement Jump to content
Sign in to follow this  
lomateron

identifying UDP sockets, using winsock

This topic is 1875 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I created a server that has a UDP socket then it recieves data from a client using:

 

recvfrom(ConnectSocket, internetbuf, 62, 0, (sockaddr*)&unknwSender, &sizeSocke);

 

then i take "unknwSender" and add it to this array:

 

SOCKADDR_STORAGE addrClients[MAX_NUM_PLAYERS]; 

 

then the next time I recieve data using recvfrom() I take again "unknwSender" and I go trough the array comparing "unknwSender" with the ones that are in the array to know if "unknwSender" has already sent to me data, I use this comparison:

 

for(...)

{

  if(
addrClients.ss_family==unknwSender.ss_family && 
addrClients.__ss_pad1==unknwSender.__ss_pad1 &&
addrClients.__ss_pad2==unknwSender.__ss_pad2 &&
addrClients.__ss_align==unknwSender.__ss_align){ //found it}
}
 
I am just a starter and this way of identifying the unknown sender is the first thing that came to my mind.
Is this the common way to do it?
If yes,is the comparison correct?
 

Share this post


Link to post
Share on other sites
Advertisement

Why don't you cast to SOCKADDR_IN (or SOCKADDR_IN6, depending on ss_family) and identify senders with the combination of sin_port and sin_addr? That's what one would normally do.

 

Comparing some "undefined" padding fields isn't very intuitive (I can't tell by looking at your code whether it's correct or not, it might incidentially do the correct comparison, but who knows!).

 

Note: If you're worried about that cast, this is something entirely legitimate and commonplace. SOCKADDR_STORAGE is merely a big 256-byte "blob" that is "guaranteed to be large enough" (such or similar is the wording) to hold any kind of SOCKADDR type of stuff, and it's legal to cast between SOCKADDR_IN/SOCKADDR_IN6 and the SOCKADDR used by the socket API and back. Of course you need to cast to the correct type so it is meaningful, which is why there is a "family" field as the first member of all these structs.

Edited by samoth

Share this post


Link to post
Share on other sites

lomateron: Your comparison will not work right. Samoth is correct: you need to understand what the address format is, and compare the proper fields (sin_port, sin_addr, for ipv4.)

If you want to support "whatever" without knowing for sure, then you need to first zero out the buffer for the address before calling recvfrom(), and then you need to use memcmp() to compare the full size you actually received. This will likely lead to more complex code than just accepting ipv4 and using that for comparison.

Share this post


Link to post
Share on other sites

One other thing to always keep in mind with recvfrom is that the sender data is actually provided by the remote machine; it isn't trustworthy. It is trivial to spoof UDP packets as coming from any address and port.

Share this post


Link to post
Share on other sites

One other thing to always keep in mind with recvfrom is that the sender data is actually provided by the remote machine; it isn't trustworthy. It is trivial to spoof UDP packets as coming from any address and port.

Well yes, but that's generally true for any datagram of any IP based protocol that comes in. Every datagram on the wire has its source address and port provided by the sender, with no verification. The only reason spoofing doesn't work quite so trivially with TCP is the sequence number, which you'd have to guess right, and which usually starts at a random value.

 

But in general, given a machine with root access (so it can open a raw socket) anyone could "trivially" spoof TCP packets as well, if only they could guess the sequence number correct. Acknowledging received data might be another issue (since you don't receive anything, so you don't know what to acknowledge), but you do not necessarily have to acknowledge anything in order to send commands. That's why any sane UDP-based protocol includes a sequence number (or another, better means of verification), too.

Edited by samoth

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!