Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


#Actualsamoth

Posted 03 July 2013 - 11:05 AM

This idea about using object's memory address is just brilliant! Though I'm afraid I'm still not pro enough to implement it tongue.png but I would like to find out sth more about this if you don't mind ^^.

I'm not sure how could it work? The server would create an object on its side and would send it to client together with its memory address? Then client would have to create the object in the same memory location, as it had been created on the server, using sth like http://www.parashift.com/c++-faq-lite/placement-new.html? But do I have certainty that the memory address which was free on the server will be free on the client as well? Or maybe I'm completely wrong with my assumptions?tongue.png

 

Rather the client would obtain "some number" from the server that it uses to refer to an object. It doesn't know where the server had that number from, the server could have used sequential numbers or pulled a random number out of its rear opening.

 

The client doesn't need to know, since what the number is or where it came from is entirely irrelevant. If the server tells you "Your friend Joe logged in as 43664", and later "43664 is messaging you", or you tell the server "I am casting a 'heal' spell at 2352978",  everybody who is involved knows what to do with the information.

 

Now, as to where the number came from, this could be just the memory address of the object as stored on the server.

 

There exists one big problem, however. Imagine "Joe" logs off and "Jim" (whom you do not know at all!) logs in. Joe logging off means the object is destroyed and the allocator puts the now invalid memory location to its free list. As Jim logs in, the allocator spits out the same address again from the top of its free list (this is common allocator behaviour, because it's cache-friendly).

 

As it happens, Jim is an annoying person who asks random people for cash. So eventually the server sends you "43664 is telling you 'got any cash for me?'". And of course, your client knows that 43664 is your friend Joe. So you see that your friend Joe needs money and you give him some. Bang.

 

Let's say that your objects have a size of 16 bytes (and the first one is properly aligned), this means that in every object's address the lowest 4 bits are zero.

Therefore, when you free an object and your allocator reclaims the memory address into its free-list, it can increment a 4-bit counter in those useless bits.

 

When Joe logs off (i.e. Joe's object is destroyed), the allocator puts the memory block at 43664 back to the free-list. But before doing so, it increments the counter, so the pointer becomes 43665. When Jim logs in, the allocator returns 43665 (and on subsequent iterations, 43666, 43667, and so on up to 43679, after which it wraps back to 43664). This could happen in the server's logic outside the allocator too, of course (doesn't matter how it's done).

 

Now, what's important, the logic in the server knows about this pointer modification, so before doing anything with a pointer obtained from the allocator, it does an & 0xfffffff0 operation on it. This is effectively a no-op on a fresh pointer, and properly aligns any recycled "meddled" pointer back to the correct address. However, the server tells the client "43665", not "43664". Your client doesn't know any of this and doesn't care where the number came from. However, it can tell that 43664 and 43665 are not the same number, so this is most definitely not Joe.


#2samoth

Posted 03 July 2013 - 11:05 AM

This idea about using object's memory address is just brilliant! Though I'm afraid I'm still not pro enough to implement it tongue.png but I would like to find out sth more about this if you don't mind ^^.

I'm not sure how could it work? The server would create an object on its side and would send it to client together with its memory address? Then client would have to create the object in the same memory location, as it had been created on the server, using sth like http://www.parashift.com/c++-faq-lite/placement-new.html? But do I have certainty that the memory address which was free on the server will be free on the client as well? Or maybe I'm completely wrong with my assumptions?tongue.png

 

Rather the client would obtain "some number" from the server that it uses to refer to an object. It doesn't know where the server had that number from, the server could have used sequential numbers or pulled a random number out of its rear opening.

 

The client doesn't need to know, since what the number is or where it came from is entirely irrelevant. If the server tells you "Your friend Joe logged in as 43664", and later "43664 is messaging you", or you tell the server "I am casting a 'heal' spell at 2352978",  everybody who is involved knows what to do with the information.

 

Now, as to where the number came from, this could be just the memory address of the object as stored on the server.

 

There exists one big problem, however. Imagine "Joe" logs off and "Jim" (whom you do not know at all!) logs in. Joe logging off means the object is destroyed and the allocator puts the now invalid memory location to its free list. As Jim logs in, the allocator spits out the same address again from the top of its free list (this is common allocator behaviour, because it's cache-friendly).

 

As it happens, Jim is an annoying person who asks random people for cash. So eventually the server sends you "43664 is telling you 'got any cash for me?'". And of course, your client knows that 43664 is your friend Joe. So you see that your friend Joe needs money and you give him some. Bang.

 

Let's say that your objects have a size of 16 bytes (and the first one is properly aligned), this means that in every object's address the lowest 4 bits are zero.

Therefore, when you free an object and your allocator reclaims the memory address into its free-list, it can increment a 4-bit counter in those useless bits.

 

When Joe logs off (i.e. Joe's object is destroyed), the allocator puts the memory block at 43664 back to the free-list. But before doing so, it increments the counter, so the pointer becomes 43665. When Jim logs in, the allocator returns 43665 (and on subsequent iterations, 43666, 43667, and so on up to 43679, after which it wraps back to 43664). This could happen in the server's logic outside the allocator too, of course (doesn't matter how it's done).

 

Now, what's important, the logic in the server knows about this pointer modification, so before doing anything with a pointer obtained from the allocator, it does an & 0xfffffff0 operation on it. This is effectively a no-op on fresh pointer, and properly aligns any recycled "meddled" pointer back to the correct address. However, the server tells the client "43665", not "43664". Your client doesn't know any of this and doesn't care where the number came from. However, it can tell that 43664 and 43665 are not the same number, so this is most definitely not Joe.


#1samoth

Posted 03 July 2013 - 10:43 AM

This idea about using object's memory address is just brilliant! Though I'm afraid I'm still not pro enough to implement it tongue.png but I would like to find out sth more about this if you don't mind ^^.

I'm not sure how could it work? The server would create an object on its side and would send it to client together with its memory address? Then client would have to create the object in the same memory location, as it had been created on the server, using sth like http://www.parashift.com/c++-faq-lite/placement-new.html? But do I have certainty that the memory address which was free on the server will be free on the client as well? Or maybe I'm completely wrong with my assumptions?tongue.png

 

Rather the client would obtain "some number" from the server that it uses to refer to an object. It doesn't know where the server had that number from, the server could have used sequential numbers or pulled a random number out of its rear opening.

 

The client doesn't need to know, since what the number is or where it came from is entirely irrelevant. If the server tells you "Your friend Joe logged in as 43664", and later "43664 is messaging you", or you tell the server "I am casting a 'heal' spell at 2352978",  everybody who is involved knows what to do with the information.

 

Now, as to where the number came from, this could be just the memory address of the object as stored on the server.

 

There exists one big problem, however. Imagine "Joe" logs off and "Jim" (whom you do not know at all!) logs in. Joe logging off means the object is destroyed and the allocator puts the now invalid memory location to its free list. As Jim logs in, the allocator spits out the same address again from the top of its free list (this is common allocator behaviour, because it's cache-friendly).

 

As it happens, Jim is an annoying person who asks random people for cash. So eventually the server sends you "43664 is telling you 'got any cash for me?'". And of course, your client knows that 43664 is your friend Joe. So you see that your friend Joe needs money and you give him some. Bang.

 

Let's say that your objects have a size of 16 bytes (and the first one is properly aligned), this means that in every object's address the lowest 4 bits are zero.

Therefore, when you free an object and your allocator reclaims the memory address into its free-list, it can increment a 4-bit counter in those useless bits.

 

When Joe logs off, the allocator puts 43664 back to the free-list. But before doing so, it increments the counter, so the pointer becomes 43665. When Jim logs in, the allocator returns 43665 (and on subsequent iterations, 43666, 43667, and so on up to 43679, after which it wraps back to 43664).

 

Now, what's important, the logic in the server knows this, so before doing anything with a pointer obtained from the allocator, it does an & 0xfffffff0 operation on it, which properly aligns any meddled pointer back to the correct address. However, the server tells the client "43665", not "43664". Your client doesn't know and doesn't care where the number came from. However, it does see (and does care) that it's a different number, so this is most definitely not Joe.


PARTNERS