Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Two physical packets per sf::Packet?  (Read 8673 times)

0 Members and 1 Guest are viewing this topic.

nitrix

  • Newbie
  • *
  • Posts: 27
    • View Profile
Two physical packets per sf::Packet?
« Reply #15 on: December 08, 2011, 05:58:49 am »
One more thing to consider even with the current implementation:

If somebody sends a size of 0xFFFFFFFF to the server but no data,
the server will wait forever on the TcpSocket::Receive(packet) and thus block any communications with other clients until data is fully received.

This is quite a huge flaw in my opinion. What I did with my previous server, every connections created a Client object with a buffer. When a packet was received, we would read as much data as we could and push it to the client's buffer. Once there's enough bytes received, it was processed.

So if Receive is really blocking (and I think it is), that's a problem for server using a selector. In a threaded environment it'd be fine... but again, not for selector servers.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Two physical packets per sf::Packet?
« Reply #16 on: December 08, 2011, 08:08:52 am »
Quote
If somebody sends a size of 0xFFFFFFFF to the server but no data

Anybody can send any corrupt data. Packet size is just one special case. Packets are not at all made for safety, if someone sends a fake packet full of crap from its own client then there's nothing you can do against it.

SFML is a simple library, if you need a robust one with a lot of checks and tricks to ensure data validity, then you're using the wrong library ;)

Quote
When a packet was received, we would read as much data as we could and push it to the client's buffer. Once there's enough bytes received, it was processed.

That's good in an asynchronous environment -- you do stuff in the background, and notify the user when everything's done. But SFML is at a lower level: when user calls Receive he expects the whole packet to be filled when the function returns.
Laurent Gomila - SFML developer

nitrix

  • Newbie
  • *
  • Posts: 27
    • View Profile
Two physical packets per sf::Packet?
« Reply #17 on: December 08, 2011, 10:03:59 am »
I think you misunderstood my post.

Corrupted data isn't a big deal. SFML doesn't have to do thoses checks, it's our job. For example: If the player wants to move to a coordinates that doesn't exist, we have to check that. When he pickup an item ID, interact with something.. those are integers we can validate ourselves with the game mechanics.

The problem comes from the fact SFML only provides a blocking Receive() function. With this API, you can't retrieve partial data and build a network manager on top. This results in a poor system where you can't control the server flow anymore! (When using a socket selector) Immagine a hacker send to your server a packet size without the data... ALL CONNECTIONS are interrupted because of Receive() waiting for more bytes it'll never receive...

---

Anyway, I think I'll use SFML for the graphics and ENet for the network. Thanks god you divided your project into smaller libraries so when can cherry-pick what we need ;)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Two physical packets per sf::Packet?
« Reply #18 on: December 08, 2011, 10:28:04 am »
Quote
Immagine a kid give to SFML a packet size he doesn't intend to send at all...

That's not supposed to happen, so SFML doesn't handle it. Like I said, SFML packets can easily be hacked with fake data, it's not meant to be a robust mechanism.

Quote
The problem comes from the fact SFML only provides a blocking Receive() function. You can't retrieve partial data and build a network manager on top.

It's not a problem, rather a design choice. Packets are made so that you don't have to worry about message boundaries. If you want to, then send/receive raw bytes, not packets.

I understand your conern, but what you want is incompatible with sf::Packet. But you can still use Send(const char*) and/or non-blocking sockets to build your own network manager.
Laurent Gomila - SFML developer

nitrix

  • Newbie
  • *
  • Posts: 27
    • View Profile
Two physical packets per sf::Packet?
« Reply #19 on: December 08, 2011, 10:35:07 am »
Oh wait. If we exclude sf::Packet, isn't Receive(const char*,size,...) blocking too? I don't need the fancy packets, I just want to read/write raw data through SFML in a way that isn't blocking..

I might owe you some excuses ahah xD Annnnd a beer if I remember right ;)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Two physical packets per sf::Packet?
« Reply #20 on: December 08, 2011, 10:42:28 am »
Socket can be made non-blocking
Code: [Select]
socket.SetBlocking(false);
Laurent Gomila - SFML developer

nitrix

  • Newbie
  • *
  • Posts: 27
    • View Profile
Two physical packets per sf::Packet?
« Reply #21 on: December 08, 2011, 10:47:15 am »
. . . right. Okay I'm sorry. I'll implement the said network manager now then x]

Oh well at least its a good warning to anybody who uses blocking sockets + sf::Packet for production. A custom implementation is better.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Two physical packets per sf::Packet?
« Reply #22 on: December 08, 2011, 11:09:50 am »
You can even use sf::Packet to encode/decode the data (to get rid of endianness and types size problems), but send/receive their contents yourself.
Laurent Gomila - SFML developer