From 3d1c77dc57687b7ae995dc1aeaf65bdee96341c6 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Fri, 26 Jul 2013 10:24:56 -0400 Subject: [PATCH] Added basic Local/LAN discovery. --- core/CMakeLists.txt | 1 + core/LAN_discovery.c | 78 ++++++++++++++++++++++++++++++++++++++++++++ core/LAN_discovery.h | 28 ++++++++++++++++ core/Messenger.c | 21 +++++++++++- core/Messenger.h | 1 + core/network.c | 2 +- 6 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 core/LAN_discovery.c create mode 100644 core/LAN_discovery.h diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index ab4ff4bc..6ddd5b9b 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -11,6 +11,7 @@ set(core_sources Lossless_UDP.c net_crypto.c friend_requests.c + LAN_discovery.c Messenger.c) add_library(core ${core_sources}) diff --git a/core/LAN_discovery.c b/core/LAN_discovery.c new file mode 100644 index 00000000..a19e4126 --- /dev/null +++ b/core/LAN_discovery.c @@ -0,0 +1,78 @@ +/* LAN_discovery.c + * + * LAN discovery implementation. + * + */ + +#include "routing.h" + + +/*Return the broadcast ip + TODO: make it return the real one, not the 255.255.255.255 one.*/ +IP broadcast_ip() +{ + IP ip; + ip.i = ~0; + return ip; +} + +/*return 0 if ip is a LAN ip + return -1 if it is not */ +int LAN_ip(IP ip) +{ + if(ip.c[0] == 127)/* Loopback */ + { + return 0; + } + if(ip.c[0] == 10)/* 10.0.0.0 to 10.255.255.255 range */ + { + return 0; + } + if(ip.c[0] == 172 && ip.c[1] >= 16 && ip.c[1] <= 31)/* 172.16.0.0 to 172.31.255.255 range */ + { + return 0; + } + if(ip.c[0] == 192 && ip.c[1] == 168) /* 192.168.0.0 to 192.168.255.255 range */ + { + return 0; + } + if(ip.c[0] == 169 && ip.c[1] == 254 && ip.c[2] != 0 && ip.c[2] != 255)/* 169.254.1.0 to 169.254.254.255 range */ + { + return 0; + } + return -1; +} + +int handle_LANdiscovery(uint8_t * packet, uint32_t length, IP_Port source) +{ + if(LAN_ip(source.ip) == -1) + { + return 1; + } + if(length != crypto_box_PUBLICKEYBYTES + 1) + { + return 1; + } + DHT_bootstrap(source, packet + 1); + return 0; +} + + +int send_LANdiscovery(uint16_t port) +{ + uint8_t data[crypto_box_PUBLICKEYBYTES + 1]; + data[0] = 32; + memcpy(data + 1, self_public_key, crypto_box_PUBLICKEYBYTES); + IP_Port ip_port = {broadcast_ip(), port}; + return sendpacket(ip_port, data, 1 + crypto_box_PUBLICKEYBYTES); +} + + +int LANdiscovery_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) +{ + if(packet[0] == 32) + { + return handle_LANdiscovery(packet, length, source); + } + return 1; +} diff --git a/core/LAN_discovery.h b/core/LAN_discovery.h new file mode 100644 index 00000000..7448abac --- /dev/null +++ b/core/LAN_discovery.h @@ -0,0 +1,28 @@ +/* LAN_discovery.h + * + * LAN discovery implementation. + * + */ + + +#ifndef LAN_DISCOVERY_H +#define LAN_DISCOVERY_H + + +#include "DHT.h" + + +/*Send a LAN discovery pcaket to the broadcast address with port port*/ +int send_LANdiscovery(uint16_t port); + + +/* if we receive a packet we call this function so it can be handled. + return 0 if packet is handled correctly. + return 1 if it didn't handle the packet or if the packet was shit. */ +int LANdiscovery_handlepacket(uint8_t * packet, uint32_t length, IP_Port source); + + + + + +#endif diff --git a/core/Messenger.c b/core/Messenger.c index d58e895c..faa3cefc 100644 --- a/core/Messenger.c +++ b/core/Messenger.c @@ -530,6 +530,22 @@ static void doInbound() } } +/*Interval in seconds between LAN discovery packet sending*/ +#define LAN_DISCOVERY_INTERVAL 60 + +static uint32_t last_LANdiscovery; + +/*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/ +static void LANdiscovery() +{ + if(last_LANdiscovery + LAN_DISCOVERY_INTERVAL < unix_time()) + { + send_LANdiscovery(htons(PORT)); + last_LANdiscovery = unix_time(); + } +} + + /* the main loop that needs to be run at least 200 times per second. */ void doMessenger() { @@ -541,7 +557,8 @@ void doMessenger() #ifdef DEBUG /* if(rand() % 3 != 1) //simulate packet loss */ /* { */ - if(DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port) && friendreq_handlepacket(data, length, ip_port)) + if(DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port) && + friendreq_handlepacket(data, length, ip_port) && LANdiscovery_handlepacket(data, length, ip_port)) { /* if packet is discarded */ printf("Received unhandled packet with length: %u\n", length); @@ -556,6 +573,7 @@ void doMessenger() DHT_handlepacket(data, length, ip_port); LosslessUDP_handlepacket(data, length, ip_port); friendreq_handlepacket(data, length, ip_port); + LANdiscovery_handlepacket(data, length, ip_port); #endif } @@ -564,6 +582,7 @@ void doMessenger() doNetCrypto(); doInbound(); doFriends(); + LANdiscovery(); } /* returns the size of the messenger data (for saving) */ diff --git a/core/Messenger.h b/core/Messenger.h index c0432e68..1067d156 100644 --- a/core/Messenger.h +++ b/core/Messenger.h @@ -29,6 +29,7 @@ #include "net_crypto.h" #include "DHT.h" #include "friend_requests.h" +#include "LAN_discovery.h" #ifdef __cplusplus extern "C" { diff --git a/core/network.c b/core/network.c index 5aa0d304..6a4d0bce 100644 --- a/core/network.c +++ b/core/network.c @@ -144,7 +144,7 @@ int init_networking(IP ip, uint16_t port) /*Enable broadcast on socket*/ int broadcast = 1; setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&broadcast, sizeof(broadcast)); - + /* Set socket nonblocking */ #ifdef WIN32 /* I think this works for windows */