101 lines
3.0 KiB
C
101 lines
3.0 KiB
C
#define P4_NETWORK_FROM ((plugin_t){3, 0, 0, 1})
|
|
|
|
/*
|
|
Handle an incoming message, and transmit it to the right module
|
|
|
|
@param buf the message to handle
|
|
@param numbytes the amount of bytes of the message (buf's size)
|
|
@return SUCCESS if everything is ok
|
|
*/
|
|
static int p_recv_message_handle_msg(char *buf, int numbytes) {
|
|
if ((size_t)numbytes < sizeof(p3_msg_t)) {
|
|
printf("invalid msg (received %lu bytes instead of %lu)", (size_t)numbytes, sizeof(p3_msg_t));
|
|
return ERR_INVALID_MSG;
|
|
}
|
|
p3_msg_t *packet = (p3_msg_t*)buf;
|
|
char *body = (buf + sizeof(p3_msg_t));
|
|
p_printf_packet(packet);
|
|
// TODO: reallocate the buf to the heap ... ?
|
|
// TODO: if destination_host == current_host {} else { forward_to_host }
|
|
api_send_message(packet->destination_plugin, body, (size_t)packet->body_length, 1);
|
|
// TODO: send the aknowledgement and then use the packet
|
|
return SUCCESS;
|
|
}
|
|
|
|
/*
|
|
TODO
|
|
Handle an incoming ACK
|
|
|
|
@param buf the ack to handle
|
|
@param numbutes the amount of bytes to process
|
|
@return SUCCESS if everything is ok
|
|
*/
|
|
static int p_recv_message_handle_ack(char *buf, int numbytes) {
|
|
if ((size_t)numbytes != sizeof(p3_ack_t)) {
|
|
printf("invalid ack (received %lu bytes instead of %lu)", (size_t)numbytes, sizeof(p3_ack_t));
|
|
return ERR_INVALID_ACK;
|
|
}
|
|
p3_ack_t *packet = (p3_ack_t*)buf;
|
|
(void)packet;
|
|
// TODO: validate that the packet.packet_id has been sent
|
|
// TODO: then send it to the right plugin
|
|
return SUCCESS;
|
|
}
|
|
|
|
/*
|
|
Handles an incoming message (read the socket, and handle)
|
|
*/
|
|
static int p_recv_message() {
|
|
if (server_p == -1)
|
|
return -1;
|
|
int numbytes;
|
|
struct sockaddr_storage their_addr;
|
|
char buf[sizeof(p3_msg_t) + BODY_LEN + 1];
|
|
socklen_t addr_len;
|
|
char s[INET6_ADDRSTRLEN];
|
|
|
|
struct timeval tv;
|
|
fd_set readfds;
|
|
tv.tv_sec = 0;
|
|
tv.tv_usec = 10;
|
|
FD_ZERO(&readfds);
|
|
FD_SET(server_p, &readfds);
|
|
select(server_p + 1, &readfds, NULL, NULL, &tv);
|
|
|
|
printf("waiting to recvfrom...\n");
|
|
if (!FD_ISSET(server_p, &readfds)) {
|
|
printf("no datagram ready!\n");
|
|
return ERR_NO_MESSAGE; // no packet
|
|
}
|
|
printf("datagram ready!\n");
|
|
|
|
addr_len = sizeof their_addr;
|
|
if ((numbytes = recvfrom(server_p, buf, sizeof(p3_msg_t) + BODY_LEN , 0, (struct sockaddr *)&their_addr, &addr_len)) == -1) {
|
|
perror("recvfrom");
|
|
return ERR_READ;
|
|
}
|
|
|
|
printf("got packet from %s\n", inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s));
|
|
printf("packet is %d bytes long\n", numbytes);
|
|
buf[numbytes] = 0;
|
|
/* printf("packet contains \"%s\"\n\n", buf); // debug test */
|
|
|
|
if ((size_t)numbytes >= sizeof(magic_number_t)) {
|
|
magic_number_t *mn = (void *)buf;
|
|
if (mn->value == MN_MSG) {
|
|
return p_recv_message_handle_msg(buf, numbytes);
|
|
}
|
|
else if (mn->value == MN_ACK) {
|
|
return p_recv_message_handle_ack(buf, numbytes);
|
|
}
|
|
else {
|
|
printf("unknown magic number (%x)\n", mn->value);
|
|
return ERR_INVALID_HEADER;
|
|
}
|
|
}
|
|
else {
|
|
printf("garbage received\n");
|
|
return ERR_INVALID_HEADER;
|
|
}
|
|
}
|