By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,406 Members | 1,020 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,406 IT Pros & Developers. It's quick & easy.

recvfrom gives empty string

P: n/a
I have declared the following struct:
struct PropagateInfo {
string type; // "registration", "gossip", "termination"
int initiatePeerID;
};

which I used as follows:

PropagateInfo* initiatePeerInfo = new PropagateInfo;
initiatePeerInfo->type = type; // type is set to "registration"
initiatePeerInfo->initiatePeerID = ID;

cout << "type before sending to overseer: " << initiatePeerInfo->type << \
endl; // prints "registration"

// sending the struct initatePeerInfo to the server
if ( (numBytes = sendto(sockfd, (void*)initiatePeerInfo, \
MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&serv_addr, sizeof(struct \
sockaddr))) == -1 ) {
cerr << "send to: " << strerror(errno) << endl;
exit(1);
}
cout << "bytes sent: " << numBytes << endl; // prints 512
/**** server side *****/
numBytes = recvfrom( sockfd, initiatePeer, MAX_UDP_PACKET_SIZE, 0, (struct
sockaddr *) &peer_addr, &addrLen );
// I have also tried sizeof(struct PropagateInfo) instead of
MAX_UDP_PACKET_SIZE

cout << "num bytes received: " << numBytes << endl; // prints 512
initiatePeerID = ((PropagateInfo*)initiatePeer)->initiatePeerID;
cout << "initiatePeerID: " << initiatePeerID << endl; // prints the
correct ID

type = ((PropagateInfo*)initiatePeer)->type;
// error - nothing (i.e. "") is printed!!!
cout << "type after receiving: " << type << endl;

output:
type after receiving:

my question:
Why is ((PropagateInfo*)initiatePeer)->type "registration" before sendto;
but "" after recvfrom?!

Thanks for your help.

Documentation:
http://linux.com.hk/PenguinWeb/manpa...send&section=2
Jul 23 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
"William" <wh******@student.cs.uwaterloo.ca> wrote...
I have declared the following struct:
struct PropagateInfo {
string type; // "registration", "gossip", "termination"
Keep in mind that 'string' object does not _itself_ contain the chars
it consists of. It allocates it elsewhere, usually in free store. So,
writing out contents of 'type' as if they were consecutive bytes does
not accomplish writing out "registration" even if type->c_str() actually
yields "registration". That's the problem with serialisation in C++,
it's just not that simple.
int initiatePeerID;
};

[...]

Jul 23 '05 #2

P: n/a
William schrieb:
I have declared the following struct:
struct PropagateInfo {
string type; // "registration", "gossip", "termination"
int initiatePeerID;
};
[snip]
// sending the struct initatePeerInfo to the server
if ( (numBytes = sendto(sockfd, (void*)initiatePeerInfo, \
MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&serv_addr, sizeof(struct \
sockaddr))) == -1 ) {
cerr << "send to: " << strerror(errno) << endl;
exit(1);
}
cout << "bytes sent: " << numBytes << endl; // prints 512
In addition to what Victor said, there is a *major* problem with your
code, plus a few smaller ones:

* the cast to void* is not necessary, but that you felt the need to use
it should have rung every available alarm bell ;)
* use C++ style casts instead
* The big one: you're telling sendto() to send MAX_UDP_PACKET_SIZE
bytes, which is almost guaranteed to be more than sizeof( PropagateInfo
), resulting in undefined behaviour and the potential for very nasty
things to happen. Now sendto() only reads the data you pass, so it's
fortunately only an invalid memory read. The output of 512 should warn
you. PropagateInfo as declared above is never going to be 512 bytes
large...
/**** server side *****/
numBytes = recvfrom( sockfd, initiatePeer, MAX_UDP_PACKET_SIZE, 0, (struct
sockaddr *) &peer_addr, &addrLen );
* And now for the really big one:
Here you're doing the same, but this time around with an operation
(recvfrom()) that will _write_ past the end of initiatePeer. This kind
of bug (buffer overflow) is the number one cause for security problems
in software, especially when it comes to networking.
// I have also tried sizeof(struct PropagateInfo) instead of
MAX_UDP_PACKET_SIZE
That would have been correct except for the more general problem as
mentioned by Victor.
cout << "num bytes received: " << numBytes << endl; // prints 512


You're quite lucky this statement was still executed instead of your
program crashing. Actually, you're not so lucky because a crash would
have had more warning potential than a somewhat working program :-)

With code as above in a program that receives data from the network,
you're inviting everyone who can send packets to the machine it's
running on to play with it. It shouldn't take more than a few minutes
to create a UDP packet that will result in your program executing any
code on your machine to the sender's delight. Remember, not only your
client can send data to it - firewalls provide some protection, but
maybe you intend your server to be connectable from the outside...

Please get more familiar with how pointers work before you consider
using them in networked applications. And memorise this: Never trust
any data received from the network to be wellformed and benign - the
same holds for any other kind of input. Expect the unexpected and write
code that will cope nicely with the most bizarre input data imaginable.

That said, I'm not at all trying to prevent you from exploring the world
of socket programming nor pointers. Only the issue is very serious and
you should be aware of the security implications.

Cheers,
Malte
Jul 23 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.