I am trying to implement distance vector routing over udp. I have the following structs:
struct cost_info {
uint8_t id;
uint8_t pad;
uint16_t cost;
}__attribute__((__packed__));
struct advertisement_packet {
uint8_t type;
uint8_t version;
uint16_t num_updates;
struct cost_info data[];
}__attribute__((__packed__));
So the packets are 1 byte type, 1 byte version, 2 bytes update count, and then 4*update count bytes of data. I am using flexible array members so that I can just do
sendto(fd, pkt, sizeof(struct advertisement_packet) + pkt->num_updates * sizeof(struct cost_info), 0, addr, sizeof(struct sockaddr_in));
and send the entire thing in one packet. Sending in one packet is required. I am able to verify using wireshark that the data is being sent out correctly. On the receiving end, I do two receives. The first gets the first 4 bytes so I can know how many updates to expect. I then resize my receiver buffer accordingly and recieve 4*num_updates bytes. The issue is that this second receive fills my buffer with zeros! If I expect 12 bytes of data, I get 12 bytes of zeros. The next time I read from that socket, I get the beginning of the next packet as expected. Why would this happen?
Here is my receive code for if needed.
recvfrom(i, pkt, sizeof(struct advertisement_packet),0,NULL,0);
//reallocate more space if the incoming data will need it
if (pkt->num_updates > pkt_cost_slots) {
pkt_cost_slots *= 2;
pkt = realloc(pkt,sizeof(struct advertisement_packet) + sizeof(struct cost_info) * pkt_cost_slots);
assert(pkt);
}
//receive data
recvfrom(i,pkt->data,pkt->num_updates * sizeof(struct cost_info),0,NULL,0);