Compare commits

...

3 Commits

Author SHA1 Message Date
Juhani Krekelä bd23f43cfa Notify frotend of Speak version packets 2019-08-04 11:31:07 +03:00
Juhani Krekelä 9a2efcce2e Start working on file sending 2019-08-04 11:16:46 +03:00
Juhani Krekelä ea2523e263 Make test.sh add the veth0a and veth0b interfaces automatically 2019-08-04 11:15:28 +03:00
4 changed files with 107 additions and 29 deletions

View File

@ -22,7 +22,7 @@
#include <time.h>
#include <unistd.h>
#define EM_PROTOCOL_VERSION 0
#define EM_PROTOCOL_VERSION 1
#define EM_MESSAGE_MAX_LENGTH (1500 - 2 - 2 - 2)
#define EM_STATUS_BROADCAST_TIME (60 * 1000 + 1000 * random_byte() / 64)
#define EM_RETRANSMIT_TIME (1000 + random_byte() * 2)
@ -37,6 +37,9 @@
#define EMT_MESSAGE 5
#define EMT_ACK 6
// Version 1
#define EMT_FILE_OFFER 7
#define EMS_AVAILABLE 0
#define EMS_UNAVAILABLE 1
#define EMS_OFFLINE 2
@ -395,6 +398,14 @@ void send_ack(const unsigned char destination[6], uint16_t msgid) {
send_frame(frame, sizeof(frame));
}
void send_file_offer(const unsigned char destination[6]) {
unsigned char frame[14 + 2];
write_headers(frame, destination, 1, EMT_FILE_OFFER);
send_frame(frame, sizeof(frame));
}
void readallx(int fd, unsigned char *buf, size_t length) {
size_t completed = 0;
while (completed < length) {
@ -496,6 +507,10 @@ void read_command(void) {
send_status(broadcast_mac);
} else if (cmd == 'm') {
read_message();
} else if (cmd == 'f') {
unsigned char mac[6];
readallx(0, mac, sizeof(mac));
send_file_offer(mac);
} else {
errx(1, "Frontend sent an unknown command %c", cmd);
}
@ -631,6 +646,29 @@ bool check_utf8(const unsigned char *data, size_t data_length, bool newline_tab_
return true;
}
void handle_speak_version(const unsigned char source_mac[6], const unsigned char *data, size_t data_length) {
if (data_length < 1) {
// Too short
return;
}
unsigned char version = data[0];
if (!check_padding(data, 1, data_length)) {
// Malformed padding
return;
}
// Type of event: Speak version
writeallx(1, "v", 1);
// MAC
writeallx(1, source_mac, 6);
// Version
writeallx(1, &version, 1);
}
void handle_status(const unsigned char source_mac[6], const unsigned char *data, size_t data_length) {
if (data_length < 2) {
// Too short
@ -867,35 +905,47 @@ void process_frame(void) {
// Extract Ethermess packet type
unsigned char packet_type = frame[15];
// Process the packet based on the packet type
switch (packet_type) {
case EMT_STATUS_REQUEST:
if (check_padding(&frame[16], 0, packet_length - 16)) {
send_status(source_mac);
}
break;
// Process the packet based on the version and packet type
if (version == 0) {
switch (packet_type) {
case EMT_SPEAK_VERSION:
handle_speak_version(source_mac, &frame[16], packet_length - 16);
break;
case EMT_STATUS:
handle_status(source_mac, &frame[16], packet_length - 16);
break;
case EMT_STATUS_REQUEST:
if (check_padding(&frame[16], 0, packet_length - 16)) {
send_status(source_mac);
}
break;
case EMT_MSGID_REQUEST:
if (check_padding(&frame[16], 0, packet_length - 16)) {
send_msgid(source_mac);
}
break;
case EMT_STATUS:
handle_status(source_mac, &frame[16], packet_length - 16);
break;
case EMT_MSGID:
handle_msgid(source_mac, &frame[16], packet_length - 16);
break;
case EMT_MSGID_REQUEST:
if (check_padding(&frame[16], 0, packet_length - 16)) {
send_msgid(source_mac);
}
break;
case EMT_MESSAGE:
handle_message(source_mac, &frame[16], packet_length - 16);
break;
case EMT_MSGID:
handle_msgid(source_mac, &frame[16], packet_length - 16);
break;
case EMT_ACK:
handle_ack(source_mac, &frame[16], packet_length - 16);
break;
case EMT_MESSAGE:
handle_message(source_mac, &frame[16], packet_length - 16);
break;
case EMT_ACK:
handle_ack(source_mac, &frame[16], packet_length - 16);
break;
}
} else if (version == 1) {
switch (packet_type) {
case EMT_FILE_OFFER:
fprintf(stderr, "File offered\n"); //debg
break;
}
}
}

View File

@ -208,6 +208,9 @@ def set_status_nick(backend, status, nick):
encoded = nick.encode('utf-8')
writeall(backend, b's' + bytes([status.value, len(encoded)]) + encoded)
def send_file_offer(backend, mac):
writeall(backend, b'f' + mac)
def handle_user_command(backend, line):
global own_nick, own_status
global default_target_mac
@ -290,13 +293,17 @@ def handle_user_command(backend, line):
# Set default target of messages
default_target_mac = mac_from_name(rest)
elif command == '/sendfile':
# Send an offer to transmit the file
send_file_offer(backend, mac_from_name(rest))
elif command == '/quit':
# Quit
return 'quit'
else:
# Display usage
print('--- / <message>; /msg <target> <message>; /status [<target>]; /peers; /available; /unavailable; /nick [<nick>]; /target <target>; /quit')
print('--- / <message>; /msg <target> <message>; /status [<target>]; /peers; /available; /unavailable; /nick [<nick>]; /target <target>; /sendfile <target>; /quit')
else:
# Send message
@ -428,7 +435,14 @@ def eventloop(proc):
for fd, event in poll.poll(wait):
if fd == proc.stdout.fileno() and event & select.POLLIN:
event_type = readall(proc.stdout, 1)
if event_type == b's':
if event_type == b'v':
# Speak version
source_mac = readall(proc.stdout, 6)
version, = readall(proc.stdout, 1)
print('--- Speak version %s %i' % (format_mac(source_mac), version)) #debg
elif event_type == b's':
# Status
source_mac = readall(proc.stdout, 6)
status, = readall(proc.stdout, 1)

View File

@ -70,6 +70,12 @@ Events
Frontend receives events from the backend.
### Speak version
Format: 'v' + MAC + version (u8)
Generated when an EtherMess Speak version packet is received by the
backend.
### Status
Format: 's' + MAC + status + nick length in bytes (u8) + nick

12
test.sh
View File

@ -1,4 +1,12 @@
#!/bin/sh
LIBEXECDIR=. make &&
test -n "$(getcap ethermess-backend)" || sudo setcap CAP_NET_RAW=ep ethermess-backend &&
LIBEXECDIR=. CFLAGS=-Werror make || exit 1
test -n "$(getcap ethermess-backend)" || sudo setcap CAP_NET_RAW=ep ethermess-backend || exit 1
if ip link show veth0a > /dev/null 2>&1 || ip link show veth0b > /dev/null 2>&1
then
true
else
sudo ip link add veth0a type veth peer name veth0b || exit 1
sudo ip link set veth0a up || exit 1
sudo ip link set veth0b up || exit 1
fi
./ethermess "$@"