mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-18 20:57:56 +00:00
Refactor interface addresses to use new socket_address struct
This commit is contained in:
parent
df6af96455
commit
5f2c6e364a
@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include "constants.h"
|
||||
#include "serval.h"
|
||||
#include "mdp_client.h"
|
||||
|
@ -3,6 +3,7 @@ HDRS= fifo.h \
|
||||
overlay_buffer.h \
|
||||
overlay_address.h \
|
||||
overlay_packet.h \
|
||||
overlay_interface.h \
|
||||
rhizome.h \
|
||||
serval.h \
|
||||
keyring.h \
|
||||
|
@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "nacl.h"
|
||||
#include "overlay_address.h"
|
||||
#include "crypto.h"
|
||||
#include "overlay_interface.h"
|
||||
#include "overlay_packet.h"
|
||||
#include "keyring.h"
|
||||
#include "dataformats.h"
|
||||
|
54
lsif.c
54
lsif.c
@ -26,9 +26,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "serval.h"
|
||||
#include "conf.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
@ -61,6 +58,9 @@
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
#include "conf.h"
|
||||
#include "overlay_interface.h"
|
||||
|
||||
/* On platforms that have variable length
|
||||
ifreq use the old fixed length interface instead */
|
||||
#ifdef OSIOCGIFCONF
|
||||
@ -97,12 +97,22 @@ int scrapeProcNetRoute()
|
||||
line[0] = '\0';
|
||||
if (fgets(line,1024,f) == NULL)
|
||||
return WHYF_perror("fgets(%p,1024,\"/proc/net/route\")", line);
|
||||
|
||||
struct socket_address addr, broadcast;
|
||||
bzero(&addr, sizeof(addr));
|
||||
bzero(&broadcast, sizeof(broadcast));
|
||||
addr.addrlen = sizeof(addr.inet);
|
||||
addr.inet.sin_family = AF_INET;
|
||||
broadcast.addrlen = sizeof(addr.inet);
|
||||
broadcast.inet.sin_family = AF_INET;
|
||||
|
||||
while(line[0]) {
|
||||
int r;
|
||||
if ((r=sscanf(line,"%s %s %*s %*s %*s %*s %*s %s",name,dest,mask))==3) {
|
||||
struct in_addr addr = {.s_addr=strtol(dest,NULL,16)};
|
||||
addr.inet.sin_addr.s_addr=strtol(dest,NULL,16);
|
||||
struct in_addr netmask = {.s_addr=strtol(mask,NULL,16)};
|
||||
overlay_interface_register(name,addr,netmask);
|
||||
broadcast.inet.sin_addr.s_addr=addr.inet.sin_addr.s_addr | ~netmask.s_addr;
|
||||
overlay_interface_register(name,&addr,&broadcast);
|
||||
}
|
||||
line[0] = '\0';
|
||||
if (fgets(line,1024,f) == NULL)
|
||||
@ -126,8 +136,11 @@ lsif(void) {
|
||||
struct ifconf ifc;
|
||||
int sck;
|
||||
struct ifreq *ifr;
|
||||
struct in_addr addr, netmask;
|
||||
|
||||
struct in_addr netmask;
|
||||
struct socket_address addr, broadcast;
|
||||
bzero(&addr, sizeof(addr));
|
||||
bzero(&broadcast, sizeof(broadcast));
|
||||
|
||||
if (config.debug.overlayinterfaces) DEBUG("called");
|
||||
|
||||
/* Get a socket handle. */
|
||||
@ -146,6 +159,9 @@ lsif(void) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
broadcast.addrlen = sizeof(addr.inet);
|
||||
broadcast.inet.sin_family = AF_INET;
|
||||
|
||||
/* Iterate through the list of interfaces. */
|
||||
unsigned nInterfaces = 0;
|
||||
unsigned ofs = 0;
|
||||
@ -158,8 +174,9 @@ lsif(void) {
|
||||
if (config.debug.overlayinterfaces) DEBUGF("Skipping non-AF_INET address on %s", ifr->ifr_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
addr = ((struct sockaddr_in *)&ifr->ifr_ifru.ifru_addr)->sin_addr;
|
||||
|
||||
addr.addrlen = sizeof(addr.inet);
|
||||
bcopy(&ifr->ifr_ifru.ifru_addr, &addr.addr, addr.addrlen);
|
||||
|
||||
/* Get interface flags */
|
||||
if (ioctl(sck, SIOCGIFFLAGS, ifr) == -1)
|
||||
@ -178,7 +195,9 @@ lsif(void) {
|
||||
}
|
||||
netmask = ((struct sockaddr_in *)&ifr->ifr_ifru.ifru_addr)->sin_addr;
|
||||
|
||||
overlay_interface_register(ifr->ifr_name, addr, netmask);
|
||||
broadcast.inet.sin_addr.s_addr=addr.inet.sin_addr.s_addr | ~netmask.s_addr;
|
||||
|
||||
overlay_interface_register(ifr->ifr_name, &addr, &broadcast);
|
||||
nInterfaces++;
|
||||
}
|
||||
|
||||
@ -195,13 +214,19 @@ int
|
||||
doifaddrs(void) {
|
||||
struct ifaddrs *ifaddr, *ifa;
|
||||
char *name;
|
||||
struct in_addr addr, netmask;
|
||||
struct socket_address addr, broadcast;
|
||||
struct in_addr netmask;
|
||||
bzero(&addr, sizeof(addr));
|
||||
bzero(&broadcast, sizeof(broadcast));
|
||||
|
||||
if (config.debug.overlayinterfaces) DEBUGF("called");
|
||||
|
||||
if (getifaddrs(&ifaddr) == -1)
|
||||
return WHY_perror("getifaddr()");
|
||||
|
||||
broadcast.addrlen = sizeof(addr.inet);
|
||||
broadcast.inet.sin_family = AF_INET;
|
||||
|
||||
for (ifa = ifaddr; ifa != NULL ; ifa = ifa->ifa_next) {
|
||||
if (!ifa->ifa_addr || !ifa->ifa_netmask)
|
||||
continue;
|
||||
@ -219,10 +244,13 @@ doifaddrs(void) {
|
||||
}
|
||||
|
||||
name = ifa->ifa_name;
|
||||
addr = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
|
||||
addr.addrlen = sizeof(addr.inet);
|
||||
bcopy(ifa->ifa_addr, &addr.addr, addr.addrlen);
|
||||
|
||||
netmask = ((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;
|
||||
broadcast.inet.sin_addr.s_addr=addr.inet.sin_addr.s_addr | ~netmask.s_addr;
|
||||
|
||||
overlay_interface_register(name, addr, netmask);
|
||||
overlay_interface_register(name, &addr, &broadcast);
|
||||
}
|
||||
freeifaddrs(ifaddr);
|
||||
|
||||
|
21
mdp_client.c
21
mdp_client.c
@ -26,6 +26,7 @@
|
||||
#include "strbuf_helpers.h"
|
||||
#include "overlay_buffer.h"
|
||||
#include "overlay_address.h"
|
||||
#include "overlay_interface.h"
|
||||
#include "overlay_packet.h"
|
||||
#include "mdp_client.h"
|
||||
#include "socket.h"
|
||||
@ -36,22 +37,6 @@ int mdp_socket(void)
|
||||
return overlay_mdp_client_socket();
|
||||
}
|
||||
|
||||
static void mdp_unlink(int mdp_sock)
|
||||
{
|
||||
// get the socket name and unlink it from the filesystem if not abstract
|
||||
struct socket_address addr;
|
||||
addr.addrlen = sizeof addr.store;
|
||||
if (getsockname(mdp_sock, &addr.addr, &addr.addrlen))
|
||||
WHYF_perror("getsockname(%d)", mdp_sock);
|
||||
else if (addr.addr.sa_family==AF_UNIX
|
||||
&& addr.addrlen > sizeof addr.local.sun_family
|
||||
&& addr.addrlen <= sizeof addr.local && addr.local.sun_path[0] != '\0') {
|
||||
if (unlink(addr.local.sun_path) == -1)
|
||||
WARNF_perror("unlink(%s)", alloca_str_toprint(addr.local.sun_path));
|
||||
}
|
||||
close(mdp_sock);
|
||||
}
|
||||
|
||||
int mdp_close(int socket)
|
||||
{
|
||||
// tell the daemon to drop all bindings
|
||||
@ -63,7 +48,7 @@ int mdp_close(int socket)
|
||||
mdp_send(socket, &header, NULL, 0);
|
||||
|
||||
// remove socket
|
||||
mdp_unlink(socket);
|
||||
socket_unlink_close(socket);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -229,7 +214,7 @@ int overlay_mdp_client_close(int mdp_sockfd)
|
||||
mdp.packetTypeAndFlags = MDP_GOODBYE;
|
||||
overlay_mdp_send(mdp_sockfd, &mdp, 0, 0);
|
||||
|
||||
mdp_unlink(mdp_sockfd);
|
||||
socket_unlink_close(mdp_sockfd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -73,6 +73,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "rhizome.h"
|
||||
#include "strbuf.h"
|
||||
#include "keyring.h"
|
||||
#include "overlay_interface.h"
|
||||
|
||||
int overlayMode=0;
|
||||
|
||||
|
@ -27,13 +27,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "serval.h"
|
||||
#include "conf.h"
|
||||
#include "str.h"
|
||||
#include "overlay_address.h"
|
||||
#include "overlay_buffer.h"
|
||||
#include "overlay_interface.h"
|
||||
#include "overlay_packet.h"
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#define MAX_BPIS 1024
|
||||
#define BPI_MASK 0x3ff
|
||||
@ -476,7 +477,7 @@ int send_please_explain(struct decode_context *context, struct subscriber *sourc
|
||||
frame->destination = destination;
|
||||
frame->destinations[frame->destination_count++].destination=add_destination_ref(context->interface->destination);
|
||||
|
||||
struct network_destination *dest = create_unicast_destination(context->addr, context->interface);
|
||||
struct network_destination *dest = create_unicast_destination(&context->addr, context->interface);
|
||||
if (dest)
|
||||
frame->destinations[frame->destination_count++].destination=dest;
|
||||
|
||||
|
@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#define __SERVAL_DNA__OVERLAY_ADDRESS_H
|
||||
|
||||
#include "constants.h"
|
||||
#include "socket.h"
|
||||
|
||||
// not reachable
|
||||
#define REACHABLE_NONE 0
|
||||
@ -94,7 +95,7 @@ struct decode_context{
|
||||
int sender_interface;
|
||||
int packet_version;
|
||||
int encapsulation;
|
||||
struct sockaddr_in addr;
|
||||
struct socket_address addr;
|
||||
union{
|
||||
// only valid while decoding
|
||||
int invalid_addresses;
|
||||
|
@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "conf.h"
|
||||
#include "net.h"
|
||||
#include "socket.h"
|
||||
#include "overlay_interface.h"
|
||||
#include "strbuf.h"
|
||||
#include "strbuf_helpers.h"
|
||||
#include "overlay_buffer.h"
|
||||
@ -46,17 +47,16 @@ int overlay_last_interface_number=-1;
|
||||
struct profile_total interface_poll_stats;
|
||||
|
||||
struct sched_ent sock_any;
|
||||
struct sockaddr_in sock_any_addr;
|
||||
struct socket_address sock_any_addr;
|
||||
struct profile_total sock_any_stats;
|
||||
|
||||
static void overlay_interface_poll(struct sched_ent *alarm);
|
||||
static int re_init_socket(int interface_index);
|
||||
|
||||
static void
|
||||
overlay_interface_close(overlay_interface *interface){
|
||||
link_interface_down(interface);
|
||||
INFOF("Interface %s addr %s is down",
|
||||
interface->name, inet_ntoa(interface->address.sin_addr));
|
||||
interface->name, alloca_socket_address(&interface->address));
|
||||
unschedule(&interface->alarm);
|
||||
unwatch(&interface->alarm);
|
||||
close(interface->alarm.poll.fd);
|
||||
@ -97,12 +97,9 @@ void interface_state_html(struct strbuf *b, struct overlay_interface *interface)
|
||||
break;
|
||||
case SOCK_DGRAM:
|
||||
{
|
||||
char addrtxt[INET_ADDRSTRLEN];
|
||||
strbuf_puts(b, "Socket: DGram<br>");
|
||||
if (inet_ntop(AF_INET, (const void *)&interface->address.sin_addr, addrtxt, INET_ADDRSTRLEN))
|
||||
strbuf_sprintf(b, "Address: %s:%d<br>", addrtxt, ntohs(interface->address.sin_port));
|
||||
if (inet_ntop(AF_INET, (const void *)&interface->destination->address.sin_addr, addrtxt, INET_ADDRSTRLEN))
|
||||
strbuf_sprintf(b, "Broadcast Address: %s:%d<br>", addrtxt, ntohs(interface->destination->address.sin_port));
|
||||
strbuf_sprintf(b, "Address: %s<br>", alloca_socket_address(&interface->address));
|
||||
strbuf_sprintf(b, "Broadcast Address: %s<br>", alloca_socket_address(&interface->destination->address));
|
||||
}
|
||||
break;
|
||||
case SOCK_FILE:
|
||||
@ -115,16 +112,26 @@ void interface_state_html(struct strbuf *b, struct overlay_interface *interface)
|
||||
|
||||
// create a socket with options common to all our UDP sockets
|
||||
static int
|
||||
overlay_bind_socket(const struct sockaddr *addr, size_t addr_size, char *interface_name){
|
||||
overlay_bind_socket(const struct socket_address *addr){
|
||||
int fd;
|
||||
int reuseP = 1;
|
||||
int broadcastP = 1;
|
||||
int protocol;
|
||||
|
||||
fd = socket(PF_INET,SOCK_DGRAM,0);
|
||||
if (fd < 0) {
|
||||
WHY_perror("Error creating socket");
|
||||
return -1;
|
||||
}
|
||||
switch(addr->addr.sa_family){
|
||||
case AF_INET:
|
||||
protocol = PF_INET;
|
||||
break;
|
||||
case AF_UNIX:
|
||||
protocol = PF_UNIX;
|
||||
break;
|
||||
default:
|
||||
return WHYF("Unsupported address %s", alloca_socket_address(addr));
|
||||
}
|
||||
|
||||
fd = socket(protocol, SOCK_DGRAM, 0);
|
||||
if (fd < 0)
|
||||
return WHY_perror("Error creating socket");
|
||||
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuseP, sizeof(reuseP)) < 0) {
|
||||
WHY_perror("setsockopt(SO_REUSEADR)");
|
||||
@ -154,18 +161,7 @@ overlay_bind_socket(const struct sockaddr *addr, size_t addr_size, char *interfa
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifdef SO_BINDTODEVICE
|
||||
/*
|
||||
Limit incoming and outgoing packets to this interface, no matter what the routing table says.
|
||||
This should allow for a device with multiple interfaces on the same subnet.
|
||||
Don't abort if this fails, I believe it requires root, just log it.
|
||||
*/
|
||||
if (interface_name && setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, interface_name, strlen(interface_name)+1) < 0) {
|
||||
WHY_perror("setsockopt(SO_BINDTODEVICE)");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (bind(fd, addr, addr_size)) {
|
||||
if (bind(fd, &addr->addr, addr->addrlen)) {
|
||||
WHY_perror("Bind failed");
|
||||
goto error;
|
||||
}
|
||||
@ -187,7 +183,7 @@ overlay_interface * overlay_interface_get_default(){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// find an interface that can send a packet to this address
|
||||
// find an interface that can send a packet to this IPv4 address
|
||||
overlay_interface * overlay_interface_find(struct in_addr addr, int return_default){
|
||||
int i;
|
||||
overlay_interface *ret = NULL;
|
||||
@ -195,7 +191,8 @@ overlay_interface * overlay_interface_find(struct in_addr addr, int return_defau
|
||||
if (overlay_interfaces[i].state!=INTERFACE_STATE_UP)
|
||||
continue;
|
||||
|
||||
if ((overlay_interfaces[i].netmask.s_addr & addr.s_addr) == (overlay_interfaces[i].netmask.s_addr & overlay_interfaces[i].address.sin_addr.s_addr)){
|
||||
if (overlay_interfaces[i].address.addr.sa_family == AF_INET
|
||||
&& (overlay_interfaces[i].netmask.s_addr & addr.s_addr) == (overlay_interfaces[i].netmask.s_addr & overlay_interfaces[i].address.inet.sin_addr.s_addr)){
|
||||
return &overlay_interfaces[i];
|
||||
}
|
||||
|
||||
@ -296,25 +293,23 @@ overlay_interface_read_any(struct sched_ent *alarm)
|
||||
// for now, we don't have a graceful close for this interface but it should go away when the process dies
|
||||
static int overlay_interface_init_any(int port)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
|
||||
if (sock_any.poll.fd>0){
|
||||
// Check the port number matches
|
||||
if (sock_any_addr.sin_port != htons(port))
|
||||
return WHYF("Unable to listen to broadcast packets for ports %d & %d", port, ntohs(sock_any_addr.sin_port));
|
||||
if (sock_any_addr.inet.sin_port != htons(port))
|
||||
return WHYF("Unable to listen to broadcast packets for ports %d & %d",
|
||||
port, ntohs(sock_any_addr.inet.sin_port));
|
||||
|
||||
return 0;
|
||||
}
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
sock_any_addr.addrlen = sizeof(sock_any_addr.inet);
|
||||
sock_any_addr.inet.sin_family = AF_INET;
|
||||
sock_any_addr.inet.sin_port = htons(port);
|
||||
sock_any_addr.inet.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
sock_any.poll.fd = overlay_bind_socket((const struct sockaddr *)&addr, sizeof(addr), NULL);
|
||||
sock_any.poll.fd = overlay_bind_socket(&sock_any_addr);
|
||||
if (sock_any.poll.fd<0)
|
||||
return -1;
|
||||
|
||||
sock_any_addr = addr;
|
||||
|
||||
sock_any.poll.events=POLLIN;
|
||||
sock_any.function = overlay_interface_read_any;
|
||||
|
||||
@ -344,20 +339,15 @@ overlay_interface_init_socket(int interface_index)
|
||||
|
||||
overlay_interface_init_any(interface->port);
|
||||
|
||||
interface->alarm.poll.fd = overlay_bind_socket(
|
||||
(const struct sockaddr *)&interface->address,
|
||||
sizeof(interface->address), interface->name);
|
||||
interface->alarm.poll.fd = overlay_bind_socket(&interface->address);
|
||||
|
||||
if (interface->alarm.poll.fd<0){
|
||||
interface->state=INTERFACE_STATE_DOWN;
|
||||
return WHYF("Failed to bind interface %s", interface->name);
|
||||
}
|
||||
|
||||
if (config.debug.packetrx || config.debug.io) {
|
||||
char srctxt[INET_ADDRSTRLEN];
|
||||
if (inet_ntop(AF_INET, (const void *)&interface->address.sin_addr, srctxt, INET_ADDRSTRLEN))
|
||||
DEBUGF("Bound to %s:%d", srctxt, ntohs(interface->address.sin_port));
|
||||
}
|
||||
if (config.debug.packetrx || config.debug.io)
|
||||
DEBUGF("Bound to %s", alloca_socket_address(&interface->address));
|
||||
|
||||
interface->alarm.poll.events=POLLIN;
|
||||
watch(&interface->alarm);
|
||||
@ -365,29 +355,13 @@ overlay_interface_init_socket(int interface_index)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int re_init_socket(int interface_index){
|
||||
if (overlay_interface_init_socket(interface_index))
|
||||
return -1;
|
||||
overlay_interface *interface = &overlay_interfaces[interface_index];
|
||||
// schedule the first tick asap
|
||||
interface->alarm.alarm=gettime_ms();
|
||||
interface->alarm.deadline=interface->alarm.alarm;
|
||||
schedule(&interface->alarm);
|
||||
interface->state=INTERFACE_STATE_UP;
|
||||
INFOF("Interface %s addr %s:%d, is up",interface->name,
|
||||
inet_ntoa(interface->address.sin_addr), ntohs(interface->address.sin_port));
|
||||
|
||||
directory_registration();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns 0 if interface is successfully added.
|
||||
* Returns 1 if interface is not added (eg, dummy file does not exist).
|
||||
* Returns -1 in case of error (misconfiguration or system error).
|
||||
*/
|
||||
static int
|
||||
overlay_interface_init(const char *name, struct in_addr src_addr, struct in_addr netmask, struct in_addr broadcast,
|
||||
overlay_interface_init(const char *name, struct socket_address *addr,
|
||||
struct socket_address *broadcast,
|
||||
const struct config_network_interface *ifconfig)
|
||||
{
|
||||
int cleanup_ret = -1;
|
||||
@ -488,20 +462,14 @@ overlay_interface_init(const char *name, struct in_addr src_addr, struct in_addr
|
||||
|
||||
limit_init(&interface->destination->transfer_limit, packet_interval);
|
||||
|
||||
interface->address.sin_family=AF_INET;
|
||||
interface->address.sin_port = htons(ifconfig->port);
|
||||
|
||||
interface->destination->address.sin_family=AF_INET;
|
||||
interface->destination->address.sin_port = htons(ifconfig->port);
|
||||
interface->address = *addr;
|
||||
interface->destination->address = *broadcast;
|
||||
|
||||
interface->alarm.function = overlay_interface_poll;
|
||||
interface_poll_stats.name="overlay_interface_poll";
|
||||
interface->alarm.stats=&interface_poll_stats;
|
||||
|
||||
if (ifconfig->socket_type==SOCK_DGRAM){
|
||||
interface->address.sin_addr = src_addr;
|
||||
interface->destination->address.sin_addr = broadcast;
|
||||
interface->netmask = netmask;
|
||||
interface->local_echo = 1;
|
||||
|
||||
if (overlay_interface_init_socket(overlay_interface_count))
|
||||
@ -509,9 +477,6 @@ overlay_interface_init(const char *name, struct in_addr src_addr, struct in_addr
|
||||
}else{
|
||||
char read_file[1024];
|
||||
|
||||
interface->address.sin_addr = ifconfig->dummy_address;
|
||||
interface->netmask = ifconfig->dummy_netmask;
|
||||
interface->destination->address.sin_addr.s_addr = interface->address.sin_addr.s_addr | ~interface->netmask.s_addr;
|
||||
interface->local_echo = interface->point_to_point?0:1;
|
||||
|
||||
strbuf d = strbuf_local(read_file, sizeof read_file);
|
||||
@ -551,8 +516,7 @@ overlay_interface_init(const char *name, struct in_addr src_addr, struct in_addr
|
||||
interface->alarm.deadline=interface->alarm.alarm;
|
||||
schedule(&interface->alarm);
|
||||
interface->state=INTERFACE_STATE_UP;
|
||||
INFOF("Interface %s addr %s:%d, is up",interface->name,
|
||||
inet_ntoa(interface->address.sin_addr), ntohs(interface->address.sin_port));
|
||||
INFOF("Interface %s addr %s, is up",interface->name, alloca_socket_address(addr));
|
||||
|
||||
directory_registration();
|
||||
|
||||
@ -597,8 +561,8 @@ static void interface_read_dgram(struct overlay_interface *interface)
|
||||
}
|
||||
|
||||
struct file_packet{
|
||||
struct sockaddr_in src_addr;
|
||||
struct sockaddr_in dst_addr;
|
||||
struct socket_address src_addr;
|
||||
struct socket_address dst_addr;
|
||||
int pid;
|
||||
int payload_length;
|
||||
|
||||
@ -619,14 +583,14 @@ struct file_packet{
|
||||
unsigned char payload[1400];
|
||||
};
|
||||
|
||||
static int should_drop(struct overlay_interface *interface, struct sockaddr_in addr){
|
||||
static int should_drop(struct overlay_interface *interface, struct socket_address *addr){
|
||||
if (interface->drop_packets>=100)
|
||||
return 1;
|
||||
|
||||
if (memcmp(&addr, &interface->address, sizeof(addr))==0){
|
||||
if (cmp_sockaddr(addr, &interface->address)==0){
|
||||
if (interface->drop_unicasts)
|
||||
return 1;
|
||||
}else if (memcmp(&addr, &interface->destination->address, sizeof(addr))==0){
|
||||
}else if (cmp_sockaddr(addr, &interface->destination->address)==0){
|
||||
if (interface->drop_broadcasts)
|
||||
return 1;
|
||||
}else
|
||||
@ -670,24 +634,21 @@ static void interface_read_file(struct overlay_interface *interface)
|
||||
if (config.debug.overlayinterfaces)
|
||||
DEBUGF("Read from interface %s (filesize=%"PRId64") at offset=%d: src_addr=%s dst_addr=%s pid=%d length=%d",
|
||||
interface->name, (int64_t)length, interface->recv_offset,
|
||||
alloca_sockaddr(&packet.src_addr, sizeof packet.src_addr),
|
||||
alloca_sockaddr(&packet.dst_addr, sizeof packet.dst_addr),
|
||||
alloca_socket_address(&packet.src_addr),
|
||||
alloca_socket_address(&packet.dst_addr),
|
||||
packet.pid,
|
||||
packet.payload_length
|
||||
);
|
||||
interface->recv_offset += nread;
|
||||
if (should_drop(interface, packet.dst_addr) || (packet.pid == getpid() && !interface->local_echo)){
|
||||
if (should_drop(interface, &packet.dst_addr) || (packet.pid == getpid() && !interface->local_echo)){
|
||||
if (config.debug.packetrx)
|
||||
DEBUGF("Ignoring packet from pid=%d src_addr=%s dst_addr=%s",
|
||||
packet.pid,
|
||||
alloca_sockaddr_in(&packet.src_addr),
|
||||
alloca_sockaddr_in(&packet.dst_addr)
|
||||
alloca_socket_address(&packet.src_addr),
|
||||
alloca_socket_address(&packet.dst_addr)
|
||||
);
|
||||
}else{
|
||||
struct socket_address srcaddr;
|
||||
srcaddr.addrlen = sizeof packet.src_addr;
|
||||
srcaddr.inet = packet.src_addr;
|
||||
packetOkOverlay(interface, packet.payload, packet.payload_length, &srcaddr);
|
||||
packetOkOverlay(interface, packet.payload, packet.payload_length, &packet.src_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -886,7 +847,8 @@ int overlay_broadcast_ensemble(struct network_destination *destination, struct o
|
||||
case SOCK_DGRAM:
|
||||
{
|
||||
if (config.debug.overlayinterfaces)
|
||||
DEBUGF("Sending %zu byte overlay frame on %s to %s", len, interface->name, inet_ntoa(destination->address.sin_addr));
|
||||
DEBUGF("Sending %zu byte overlay frame on %s to %s",
|
||||
(size_t)len, interface->name, alloca_socket_address(&destination->address));
|
||||
ssize_t sent = sendto(interface->alarm.poll.fd,
|
||||
bytes, (size_t)len, 0,
|
||||
(struct sockaddr *)&destination->address, sizeof(destination->address));
|
||||
@ -921,15 +883,13 @@ int overlay_broadcast_ensemble(struct network_destination *destination, struct o
|
||||
/* Register the real interface, or update the existing interface registration. */
|
||||
int
|
||||
overlay_interface_register(char *name,
|
||||
struct in_addr addr,
|
||||
struct in_addr mask)
|
||||
struct socket_address *addr,
|
||||
struct socket_address *broadcast)
|
||||
{
|
||||
struct in_addr broadcast = {.s_addr = addr.s_addr | ~mask.s_addr};
|
||||
|
||||
if (config.debug.overlayinterfaces) {
|
||||
// note, inet_ntop doesn't seem to behave on android
|
||||
DEBUGF("%s address: %s", name, inet_ntoa(addr));
|
||||
DEBUGF("%s broadcast address: %s", name, inet_ntoa(broadcast));
|
||||
DEBUGF("%s address: %s", name, alloca_socket_address(addr));
|
||||
DEBUGF("%s broadcast address: %s", name, alloca_socket_address(broadcast));
|
||||
}
|
||||
|
||||
// Find the matching non-dummy interface rule.
|
||||
@ -958,49 +918,32 @@ overlay_interface_register(char *name,
|
||||
DEBUGF("Interface %s is explicitly excluded", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (addr->addr.sa_family==AF_INET)
|
||||
addr->inet.sin_port = htons(ifconfig->port);
|
||||
if (broadcast->addr.sa_family==AF_INET)
|
||||
broadcast->inet.sin_port = htons(ifconfig->port);
|
||||
|
||||
/* Search in the exist list of interfaces */
|
||||
int found_interface= -1;
|
||||
for(i = 0; i < overlay_interface_count; i++){
|
||||
int broadcast_match = 0;
|
||||
int name_match =0;
|
||||
if (overlay_interfaces[i].state==INTERFACE_STATE_DOWN){
|
||||
continue;
|
||||
}
|
||||
|
||||
if (overlay_interfaces[i].destination->address.sin_addr.s_addr == broadcast.s_addr)
|
||||
broadcast_match = 1;
|
||||
|
||||
name_match = !strcasecmp(overlay_interfaces[i].name, name);
|
||||
|
||||
// if we find an exact match we can stop searching
|
||||
if (name_match && broadcast_match){
|
||||
if (strcasecmp(overlay_interfaces[i].name, name)
|
||||
&& cmp_sockaddr(addr, &overlay_interfaces[i].address)==0
|
||||
&& overlay_interfaces[i].state!=INTERFACE_STATE_DOWN){
|
||||
|
||||
// mark this interface as still alive
|
||||
if (overlay_interfaces[i].state==INTERFACE_STATE_DETECTING)
|
||||
overlay_interfaces[i].state=INTERFACE_STATE_UP;
|
||||
|
||||
// try to bring the interface back up again even if the address has changed
|
||||
if (overlay_interfaces[i].state==INTERFACE_STATE_DOWN){
|
||||
overlay_interfaces[i].address.sin_addr = addr;
|
||||
re_init_socket(i);
|
||||
}
|
||||
|
||||
// we already know about this interface, and it's up so stop looking immediately
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// remember this slot to bring the interface back up again, even if the address has changed
|
||||
if (name_match && overlay_interfaces[i].state==INTERFACE_STATE_DOWN)
|
||||
found_interface=i;
|
||||
}
|
||||
|
||||
if (found_interface>=0){
|
||||
// try to reactivate the existing interface
|
||||
overlay_interfaces[found_interface].address.sin_addr = addr;
|
||||
overlay_interfaces[found_interface].destination->address.sin_addr = broadcast;
|
||||
overlay_interfaces[found_interface].netmask = mask;
|
||||
return re_init_socket(found_interface);
|
||||
}
|
||||
|
||||
/* New interface, so register it */
|
||||
if (overlay_interface_init(name, addr, mask, broadcast, ifconfig))
|
||||
if (overlay_interface_init(name, addr, broadcast, ifconfig))
|
||||
return WHYF("Could not initialise newly seen interface %s", name);
|
||||
else
|
||||
if (config.debug.overlayinterfaces) DEBUGF("Registered interface %s", name);
|
||||
@ -1039,8 +982,21 @@ void overlay_interface_discover(struct sched_ent *alarm)
|
||||
|
||||
if (j >= overlay_interface_count) {
|
||||
// New dummy interface, so register it.
|
||||
struct in_addr dummyaddr = hton_in_addr(INADDR_NONE);
|
||||
overlay_interface_init(ifconfig->file, dummyaddr, dummyaddr, dummyaddr, ifconfig);
|
||||
struct socket_address addr, broadcast;
|
||||
bzero(&addr, sizeof addr);
|
||||
bzero(&broadcast, sizeof broadcast);
|
||||
|
||||
addr.addrlen=sizeof addr.inet;
|
||||
addr.inet.sin_family=AF_INET;
|
||||
addr.inet.sin_port=htons(ifconfig->port);
|
||||
addr.inet.sin_addr=ifconfig->dummy_address;
|
||||
|
||||
broadcast.addrlen=sizeof addr.inet;
|
||||
broadcast.inet.sin_family=AF_INET;
|
||||
broadcast.inet.sin_port=htons(ifconfig->port);
|
||||
broadcast.inet.sin_addr.s_addr=ifconfig->dummy_address.s_addr | ~ifconfig->dummy_netmask.s_addr;
|
||||
|
||||
overlay_interface_init(ifconfig->file, &addr, &broadcast, ifconfig);
|
||||
}
|
||||
}
|
||||
|
||||
|
145
overlay_interface.h
Normal file
145
overlay_interface.h
Normal file
@ -0,0 +1,145 @@
|
||||
#ifndef __SERVAL_DNA__OVERLAY_INTERFACE_H
|
||||
#define __SERVAL_DNA__OVERLAY_INTERFACE_H
|
||||
|
||||
#include "socket.h"
|
||||
|
||||
#define INTERFACE_STATE_FREE 0
|
||||
#define INTERFACE_STATE_UP 1
|
||||
#define INTERFACE_STATE_DOWN 2
|
||||
#define INTERFACE_STATE_DETECTING 3
|
||||
|
||||
|
||||
struct overlay_interface;
|
||||
|
||||
// where should packets be sent to?
|
||||
struct network_destination {
|
||||
int _ref_count;
|
||||
|
||||
// which interface are we actually sending packets out of
|
||||
struct overlay_interface *interface;
|
||||
|
||||
// The network destination address
|
||||
// this may be the interface broadcast IP address
|
||||
// but could be a unicast address
|
||||
struct socket_address address;
|
||||
|
||||
// should outgoing packets be marked as unicast?
|
||||
char unicast;
|
||||
|
||||
char packet_version;
|
||||
|
||||
// should we aggregate packets, or send one at a time
|
||||
char encapsulation;
|
||||
|
||||
// time last packet was sent
|
||||
time_ms_t last_tx;
|
||||
|
||||
int min_rtt;
|
||||
int max_rtt;
|
||||
int resend_delay;
|
||||
|
||||
// sequence number of last packet sent to this destination.
|
||||
// Used to allow NACKs that can request retransmission of recent packets.
|
||||
int sequence_number;
|
||||
|
||||
// rate limit for outgoing packets
|
||||
struct limit_state transfer_limit;
|
||||
|
||||
/* Number of milli-seconds per tick for this interface, which is basically
|
||||
* related to the the typical TX range divided by the maximum expected
|
||||
* speed of nodes in the network. This means that short-range communications
|
||||
* has a higher bandwidth requirement than long-range communications because
|
||||
* the tick interval has to be shorter to still allow fast-convergence time
|
||||
* to allow for mobility.
|
||||
*
|
||||
* For wifi (nominal range 100m) it is usually 500ms.
|
||||
* For ~100K ISM915MHz (nominal range 1000m) it will probably be about 5000ms.
|
||||
* For ~10K ISM915MHz (nominal range ~3000m) it will probably be about 15000ms.
|
||||
*
|
||||
* These figures will be refined over time, and we will allow people to set
|
||||
* them per-interface.
|
||||
*/
|
||||
unsigned tick_ms;
|
||||
|
||||
// Number of milliseconds of no packets until we assume the link is dead.
|
||||
unsigned reachable_timeout_ms;
|
||||
};
|
||||
|
||||
typedef struct overlay_interface {
|
||||
struct sched_ent alarm;
|
||||
|
||||
char name[256];
|
||||
|
||||
int recv_offset; /* file offset */
|
||||
|
||||
int recv_count;
|
||||
int tx_count;
|
||||
|
||||
struct radio_link_state *radio_link_state;
|
||||
|
||||
// copy of ifconfig flags
|
||||
uint16_t drop_packets;
|
||||
char drop_broadcasts;
|
||||
char drop_unicasts;
|
||||
int port;
|
||||
int type;
|
||||
int socket_type;
|
||||
char send_broadcasts;
|
||||
char prefer_unicast;
|
||||
/* Not necessarily the real MTU, but the largest frame size we are willing to TX.
|
||||
For radio links the actual maximum and the maximum that is likely to be delivered reliably are
|
||||
potentially two quite different values. */
|
||||
int mtu;
|
||||
// can we use this interface for routes to addresses in other subnets?
|
||||
int default_route;
|
||||
// should we log more debug info on this interace? eg hex dumps of packets
|
||||
char debug;
|
||||
char local_echo;
|
||||
|
||||
unsigned int uartbps; // set serial port speed (which might be different from link speed)
|
||||
int ctsrts; // enabled hardware flow control if non-zero
|
||||
|
||||
struct network_destination *destination;
|
||||
|
||||
// can we assume that we will only receive packets from one device?
|
||||
char point_to_point;
|
||||
struct subscriber *other_device;
|
||||
|
||||
// the actual address of the interface.
|
||||
struct socket_address address;
|
||||
|
||||
struct in_addr netmask;
|
||||
|
||||
/* Use one of the INTERFACE_STATE_* constants to indicate the state of this interface.
|
||||
If the interface stops working or disappears, it will be marked as DOWN and the socket closed.
|
||||
But if it comes back up again, we should try to reuse this structure, even if the broadcast address has changed.
|
||||
*/
|
||||
int state;
|
||||
} overlay_interface;
|
||||
|
||||
/* Maximum interface count is rather arbitrary.
|
||||
Memory consumption is O(n) with respect to this parameter, so let's not make it too big for now.
|
||||
*/
|
||||
extern overlay_interface overlay_interfaces[OVERLAY_MAX_INTERFACES];
|
||||
|
||||
extern unsigned overlay_interface_count;
|
||||
|
||||
struct network_destination * new_destination(struct overlay_interface *interface, char encapsulation);
|
||||
struct network_destination * create_unicast_destination(struct socket_address *addr, struct overlay_interface *interface);
|
||||
struct network_destination * add_destination_ref(struct network_destination *ref);
|
||||
void release_destination_ref(struct network_destination *ref);
|
||||
int set_destination_ref(struct network_destination **ptr, struct network_destination *ref);
|
||||
|
||||
|
||||
void overlay_interface_discover(struct sched_ent *alarm);
|
||||
int overlay_interface_register(char *name,
|
||||
struct socket_address *addr,
|
||||
struct socket_address *broadcast);
|
||||
overlay_interface * overlay_interface_get_default();
|
||||
overlay_interface * overlay_interface_find(struct in_addr addr, int return_default);
|
||||
overlay_interface * overlay_interface_find_name(const char *name);
|
||||
int overlay_interface_compare(overlay_interface *one, overlay_interface *two);
|
||||
int overlay_broadcast_ensemble(struct network_destination *destination, struct overlay_buffer *buffer);
|
||||
void interface_state_html(struct strbuf *b, struct overlay_interface *interface);
|
||||
|
||||
#endif // __SERVAL_DNA__OVERLAY_INTERFACE_H
|
@ -23,16 +23,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "str.h"
|
||||
#include "overlay_address.h"
|
||||
#include "overlay_buffer.h"
|
||||
#include "overlay_interface.h"
|
||||
#include "overlay_packet.h"
|
||||
#include "keyring.h"
|
||||
#include "strbuf_helpers.h"
|
||||
|
||||
#define MIN_BURST_LENGTH 5000
|
||||
|
||||
struct probe_contents{
|
||||
struct sockaddr_in addr;
|
||||
unsigned char interface;
|
||||
};
|
||||
|
||||
static void update_limit_state(struct limit_state *state, time_ms_t now){
|
||||
if (state->next_interval > now || state->burst_size==0){
|
||||
return;
|
||||
@ -177,14 +174,15 @@ int load_subscriber_address(struct subscriber *subscriber)
|
||||
if (!interface)
|
||||
return WHY("Can't fund configured interface");
|
||||
}
|
||||
struct sockaddr_in addr;
|
||||
struct socket_address addr;
|
||||
bzero(&addr, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr = hostc->address;
|
||||
addr.sin_port = htons(hostc->port);
|
||||
if (addr.sin_addr.s_addr==INADDR_NONE){
|
||||
addr.addrlen = sizeof(addr.inet);
|
||||
addr.inet.sin_family = AF_INET;
|
||||
addr.inet.sin_addr = hostc->address;
|
||||
addr.inet.sin_port = htons(hostc->port);
|
||||
if (addr.inet.sin_addr.s_addr==INADDR_NONE){
|
||||
if (interface || overlay_interface_get_default()){
|
||||
if (resolve_name(hostc->host, &addr.sin_addr))
|
||||
if (resolve_name(hostc->host, &addr.inet.sin_addr))
|
||||
return -1;
|
||||
}else{
|
||||
// interface isnt up yet
|
||||
@ -192,8 +190,8 @@ int load_subscriber_address(struct subscriber *subscriber)
|
||||
}
|
||||
}
|
||||
if (config.debug.overlayrouting)
|
||||
DEBUGF("Loaded address %s:%d for %s", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port), alloca_tohex_sid_t(subscriber->sid));
|
||||
struct network_destination *destination = create_unicast_destination(addr, interface);
|
||||
DEBUGF("Loaded address %s for %s", alloca_socket_address(&addr), alloca_tohex_sid_t(subscriber->sid));
|
||||
struct network_destination *destination = create_unicast_destination(&addr, interface);
|
||||
if (!destination)
|
||||
return -1;
|
||||
int ret=overlay_send_probe(subscriber, destination, OQ_MESH_MANAGEMENT);
|
||||
@ -206,7 +204,7 @@ int
|
||||
overlay_mdp_service_probe(struct overlay_frame *frame, overlay_mdp_frame *mdp)
|
||||
{
|
||||
IN();
|
||||
if (mdp->out.src.port!=MDP_PORT_ECHO || mdp->out.payload_length != sizeof(struct probe_contents)){
|
||||
if (mdp->out.src.port!=MDP_PORT_ECHO){
|
||||
WARN("Probe packets should be returned from remote echo port");
|
||||
RETURN(-1);
|
||||
}
|
||||
@ -214,12 +212,16 @@ overlay_mdp_service_probe(struct overlay_frame *frame, overlay_mdp_frame *mdp)
|
||||
if (frame->source->reachable == REACHABLE_SELF)
|
||||
RETURN(0);
|
||||
|
||||
struct probe_contents probe;
|
||||
bcopy(&mdp->out.payload, &probe, sizeof(struct probe_contents));
|
||||
if (probe.addr.sin_family!=AF_INET)
|
||||
RETURN(WHY("Unsupported address family"));
|
||||
uint8_t interface = mdp->out.payload[0];
|
||||
struct socket_address addr;
|
||||
addr.addrlen = mdp->out.payload_length - 1;
|
||||
|
||||
RETURN(link_unicast_ack(frame->source, &overlay_interfaces[probe.interface], probe.addr));
|
||||
if (addr.addrlen > sizeof(addr.store))
|
||||
RETURN(-1);
|
||||
|
||||
bcopy(&mdp->out.payload[1], &addr.addr, addr.addrlen);
|
||||
|
||||
RETURN(link_unicast_ack(frame->source, &overlay_interfaces[interface], &addr));
|
||||
OUT();
|
||||
}
|
||||
|
||||
@ -250,25 +252,18 @@ int overlay_send_probe(struct subscriber *peer, struct network_destination *dest
|
||||
// TODO call mdp payload encryption / signing without calling overlay_mdp_dispatch...
|
||||
|
||||
overlay_mdp_encode_ports(frame->payload, MDP_PORT_ECHO, MDP_PORT_PROBE);
|
||||
// not worried about byte order here as we are the only node that should be parsing the contents.
|
||||
unsigned char *dst=ob_append_space(frame->payload, sizeof(struct probe_contents));
|
||||
if (!dst){
|
||||
op_free(frame);
|
||||
return -1;
|
||||
}
|
||||
struct probe_contents probe;
|
||||
probe.addr=destination->address;
|
||||
// get interface number
|
||||
probe.interface = destination->interface - overlay_interfaces;
|
||||
bcopy(&probe, dst, sizeof(struct probe_contents));
|
||||
|
||||
ob_append_byte(frame->payload, destination->interface - overlay_interfaces);
|
||||
ob_append_bytes(frame->payload, (uint8_t*)&destination->address.addr, destination->address.addrlen);
|
||||
|
||||
if (overlay_payload_enqueue(frame)){
|
||||
op_free(frame);
|
||||
return -1;
|
||||
}
|
||||
if (config.debug.overlayrouting)
|
||||
DEBUGF("Queued probe packet on interface %s to %s:%d for %s",
|
||||
DEBUGF("Queued probe packet on interface %s to %s for %s",
|
||||
destination->interface->name,
|
||||
inet_ntoa(destination->address.sin_addr), ntohs(destination->address.sin_port),
|
||||
alloca_socket_address(&destination->address),
|
||||
peer?alloca_tohex_sid_t(peer->sid):"ANY");
|
||||
return 0;
|
||||
}
|
||||
@ -278,11 +273,11 @@ static void overlay_append_unicast_address(struct subscriber *subscriber, struct
|
||||
{
|
||||
if ( subscriber->destination
|
||||
&& subscriber->destination->unicast
|
||||
&& subscriber->destination->address.sin_family==AF_INET
|
||||
&& subscriber->destination->address.addr.sa_family==AF_INET
|
||||
) {
|
||||
overlay_address_append(NULL, buff, subscriber);
|
||||
ob_append_ui32(buff, subscriber->destination->address.sin_addr.s_addr);
|
||||
ob_append_ui16(buff, subscriber->destination->address.sin_port);
|
||||
ob_append_ui32(buff, subscriber->destination->address.inet.sin_addr.s_addr);
|
||||
ob_append_ui16(buff, subscriber->destination->address.inet.sin_port);
|
||||
if (config.debug.overlayrouting)
|
||||
DEBUGF("Added STUN info for %s", alloca_tohex_sid_t(subscriber->sid));
|
||||
}else{
|
||||
@ -349,22 +344,22 @@ int overlay_mdp_service_stun(overlay_mdp_frame *mdp)
|
||||
|
||||
while(ob_remaining(buff)>0){
|
||||
struct subscriber *subscriber=NULL;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
// TODO explain addresses, link expiry time, resolve differences between addresses...
|
||||
|
||||
if (overlay_address_parse(NULL, buff, &subscriber)){
|
||||
break;
|
||||
}
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = ob_get_ui32(buff);
|
||||
addr.sin_port = ob_get_ui16(buff);
|
||||
struct socket_address addr;
|
||||
addr.addrlen = sizeof(addr.inet);
|
||||
addr.inet.sin_family = AF_INET;
|
||||
addr.inet.sin_addr.s_addr = ob_get_ui32(buff);
|
||||
addr.inet.sin_port = ob_get_ui16(buff);
|
||||
|
||||
if (!subscriber || (subscriber->reachable!=REACHABLE_NONE))
|
||||
continue;
|
||||
|
||||
struct network_destination *destination = create_unicast_destination(addr, NULL);
|
||||
struct network_destination *destination = create_unicast_destination(&addr, NULL);
|
||||
if (destination){
|
||||
overlay_send_probe(subscriber, destination, OQ_MESH_MANAGEMENT);
|
||||
release_destination_ref(destination);
|
||||
|
@ -57,6 +57,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "strbuf_helpers.h"
|
||||
#include "overlay_buffer.h"
|
||||
#include "overlay_address.h"
|
||||
#include "overlay_interface.h"
|
||||
#include "overlay_packet.h"
|
||||
#include "mdp_client.h"
|
||||
#include "crypto.h"
|
||||
@ -1058,20 +1059,21 @@ struct scan_state scans[OVERLAY_MAX_INTERFACES];
|
||||
|
||||
static void overlay_mdp_scan(struct sched_ent *alarm)
|
||||
{
|
||||
struct sockaddr_in addr={
|
||||
.sin_family=AF_INET,
|
||||
.sin_port=htons(PORT_DNA),
|
||||
.sin_addr={0},
|
||||
};
|
||||
struct socket_address addr;
|
||||
bzero(&addr, sizeof(addr));
|
||||
addr.addrlen = sizeof(addr.inet);
|
||||
addr.inet.sin_family=AF_INET;
|
||||
addr.inet.sin_port=htons(PORT_DNA);
|
||||
|
||||
struct scan_state *state = (struct scan_state *)alarm;
|
||||
uint32_t stop = state->last;
|
||||
if (stop - state->current > 25)
|
||||
stop = state->current+25;
|
||||
|
||||
while(state->current <= stop){
|
||||
addr.sin_addr.s_addr=htonl(state->current);
|
||||
if (addr.sin_addr.s_addr != state->interface->address.sin_addr.s_addr){
|
||||
struct network_destination *destination = create_unicast_destination(addr, state->interface);
|
||||
addr.inet.sin_addr.s_addr=htonl(state->current);
|
||||
if (addr.inet.sin_addr.s_addr != state->interface->address.inet.sin_addr.s_addr){
|
||||
struct network_destination *destination = create_unicast_destination(&addr, state->interface);
|
||||
if (!destination)
|
||||
break;
|
||||
int ret = overlay_send_probe(NULL, destination, OQ_ORDINARY);
|
||||
@ -1630,12 +1632,14 @@ static void overlay_mdp_poll(struct sched_ent *alarm)
|
||||
struct overlay_interface *interface = &overlay_interfaces[i];
|
||||
if (interface->state!=INTERFACE_STATE_UP)
|
||||
continue;
|
||||
|
||||
if (interface->address.addr.sa_family!=AF_INET)
|
||||
continue;
|
||||
scans[i].interface = interface;
|
||||
scans[i].current = ntohl(interface->address.sin_addr.s_addr & interface->netmask.s_addr)+1;
|
||||
scans[i].last = ntohl(interface->destination->address.sin_addr.s_addr)-1;
|
||||
scans[i].current = ntohl(interface->address.inet.sin_addr.s_addr & ~interface->netmask.s_addr)+1;
|
||||
scans[i].last = ntohl(interface->destination->address.inet.sin_addr.s_addr)-1;
|
||||
if (scans[i].last - scans[i].current>0x10000){
|
||||
INFOF("Skipping scan on interface %s as the address space is too large",interface->name);
|
||||
INFOF("Skipping scan on interface %s as the address space is too large (%04x %04x)",
|
||||
interface->name, scans[i].last, scans[i].current);
|
||||
continue;
|
||||
}
|
||||
scans[i].alarm.alarm=start;
|
||||
|
@ -62,6 +62,7 @@
|
||||
|
||||
#include "serval.h"
|
||||
#include "conf.h"
|
||||
#include "overlay_interface.h"
|
||||
#include "overlay_packet.h"
|
||||
#include "overlay_buffer.h"
|
||||
#include "overlay_address.h"
|
||||
|
@ -84,7 +84,7 @@ struct overlay_frame {
|
||||
int source_full;
|
||||
|
||||
// how did we receive this packet?
|
||||
overlay_interface *interface;
|
||||
struct overlay_interface *interface;
|
||||
struct sockaddr_in recvaddr;
|
||||
// packet envelope header;
|
||||
// Was it a unicast frame
|
||||
|
@ -22,9 +22,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "socket.h"
|
||||
#include "str.h"
|
||||
#include "strbuf.h"
|
||||
#include "strbuf_helpers.h"
|
||||
#include "overlay_buffer.h"
|
||||
#include "overlay_interface.h"
|
||||
#include "overlay_packet.h"
|
||||
|
||||
|
||||
struct sockaddr_in loopback;
|
||||
|
||||
|
||||
@ -259,7 +262,7 @@ int parseMdpPacketHeader(struct decode_context *context, struct overlay_frame *f
|
||||
}
|
||||
|
||||
int parseEnvelopeHeader(struct decode_context *context, struct overlay_interface *interface,
|
||||
struct sockaddr_in *addr, struct overlay_buffer *buffer){
|
||||
struct socket_address *addr, struct overlay_buffer *buffer){
|
||||
IN();
|
||||
|
||||
context->interface = interface;
|
||||
@ -387,7 +390,7 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
|
||||
}
|
||||
|
||||
if (recvaddr && recvaddr->addr.sa_family != AF_INET)
|
||||
RETURN(WHYF("Unexpected protocol family %d", recvaddr->addr.sa_family));
|
||||
RETURN(WHYF("Unexpected address %s", alloca_socket_address(recvaddr)));
|
||||
|
||||
struct overlay_frame f;
|
||||
struct decode_context context;
|
||||
@ -404,7 +407,7 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
|
||||
else
|
||||
bzero(&f.recvaddr, sizeof f.recvaddr);
|
||||
|
||||
int ret=parseEnvelopeHeader(&context, interface, recvaddr ? &recvaddr->inet : NULL, b);
|
||||
int ret=parseEnvelopeHeader(&context, interface, recvaddr, b);
|
||||
if (ret){
|
||||
ob_free(b);
|
||||
RETURN(ret);
|
||||
|
@ -18,9 +18,10 @@ along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <termios.h>
|
||||
#include "serval.h"
|
||||
#include "conf.h"
|
||||
#include <termios.h>
|
||||
#include "overlay_interface.h"
|
||||
|
||||
int overlay_packetradio_setup_port(overlay_interface *interface)
|
||||
{
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "serval.h"
|
||||
#include "conf.h"
|
||||
#include "overlay_buffer.h"
|
||||
#include "overlay_interface.h"
|
||||
#include "overlay_packet.h"
|
||||
#include "radio_link.h"
|
||||
#include "str.h"
|
||||
|
@ -178,9 +178,6 @@ int fd_showstats()
|
||||
stats = stats->_next;
|
||||
}
|
||||
|
||||
// Show periodic rhizome transfer information
|
||||
rhizome_fetch_log_short_status();
|
||||
|
||||
// Report any functions that take too much time
|
||||
if (!config.debug.timing)
|
||||
{
|
||||
|
@ -47,6 +47,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "serval.h"
|
||||
#include "conf.h"
|
||||
#include "overlay_buffer.h"
|
||||
#include "overlay_interface.h"
|
||||
#include "golay.h"
|
||||
#include "radio_link.h"
|
||||
|
||||
|
@ -706,7 +706,7 @@ void rhizome_list_release(struct rhizome_list_cursor *);
|
||||
#define MAX_RHIZOME_MANIFESTS 40
|
||||
#define MAX_CANDIDATES 32
|
||||
|
||||
int rhizome_suggest_queue_manifest_import(rhizome_manifest *m, const struct sockaddr_in *peerip, const sid_t *peersidp);
|
||||
int rhizome_suggest_queue_manifest_import(rhizome_manifest *m, const struct socket_address *addr, const sid_t *peersidp);
|
||||
rhizome_manifest * rhizome_fetch_search(const unsigned char *id, int prefix_length);
|
||||
|
||||
/* Rhizome file storage api */
|
||||
@ -994,7 +994,10 @@ enum rhizome_start_fetch_result {
|
||||
SLOTBUSY
|
||||
};
|
||||
|
||||
enum rhizome_start_fetch_result rhizome_fetch_request_manifest_by_prefix(const struct sockaddr_in *peerip, const sid_t *sidp, const unsigned char *prefix, size_t prefix_length);
|
||||
enum rhizome_start_fetch_result
|
||||
rhizome_fetch_request_manifest_by_prefix(const struct socket_address *addr,
|
||||
const sid_t *peersidp,
|
||||
const unsigned char *prefix, size_t prefix_length);
|
||||
int rhizome_any_fetch_active();
|
||||
int rhizome_any_fetch_queued();
|
||||
int rhizome_fetch_status_html(struct strbuf *b);
|
||||
|
@ -17,16 +17,19 @@ along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "serval.h"
|
||||
#include "rhizome.h"
|
||||
#include "conf.h"
|
||||
#include "str.h"
|
||||
#include "strbuf.h"
|
||||
#include "strbuf_helpers.h"
|
||||
#include <assert.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "socket.h"
|
||||
|
||||
|
||||
static int _form_temporary_file_path(struct __sourceloc __whence, rhizome_http_request *r, char *pathbuf, size_t bufsiz, const char *field)
|
||||
{
|
||||
@ -488,14 +491,15 @@ void rhizome_direct_http_dispatch(rhizome_direct_sync_request *r)
|
||||
goto end;
|
||||
}
|
||||
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(state->port);
|
||||
addr.sin_addr = *((struct in_addr *)hostent->h_addr);
|
||||
bzero(&(addr.sin_zero),8);
|
||||
struct socket_address addr;
|
||||
bzero(&addr,sizeof(addr));
|
||||
addr.addrlen = sizeof(addr.inet);
|
||||
addr.inet.sin_family = AF_INET;
|
||||
addr.inet.sin_port = htons(state->port);
|
||||
addr.inet.sin_addr = *((struct in_addr *)hostent->h_addr);
|
||||
|
||||
if (connect(sock, (struct sockaddr *)&addr, sizeof addr) == -1) {
|
||||
WHYF_perror("connect(%s)", alloca_sockaddr(&addr, sizeof addr));
|
||||
if (connect(sock, &addr.addr, addr.addrlen) == -1) {
|
||||
WHYF_perror("connect(%s)", alloca_socket_address(&addr));
|
||||
close(sock);
|
||||
goto end;
|
||||
}
|
||||
@ -693,18 +697,13 @@ void rhizome_direct_http_dispatch(rhizome_direct_sync_request *r)
|
||||
len+=m->manifest_all_bytes;
|
||||
len+=snprintf(&buffer[len],8192-len,template3,boundary);
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(state->port);
|
||||
addr.sin_addr = *((struct in_addr *)hostent->h_addr);
|
||||
bzero(&(addr.sin_zero),8);
|
||||
|
||||
sock=socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock==-1) {
|
||||
if (config.debug.rhizome_tx)
|
||||
DEBUGF("could not open socket");
|
||||
goto closeit;
|
||||
}
|
||||
if (connect(sock,(struct sockaddr *)&addr,sizeof(struct sockaddr)) == -1) {
|
||||
if (connect(sock,&addr.addr,addr.addrlen) == -1) {
|
||||
if (config.debug.rhizome_tx)
|
||||
DEBUGF("Could not connect to remote");
|
||||
goto closeit;
|
||||
|
@ -37,7 +37,7 @@ struct rhizome_fetch_candidate {
|
||||
/* Address of node offering manifest.
|
||||
Can be either IP+port for HTTP or it can be a SID
|
||||
for MDP. */
|
||||
struct sockaddr_in peer_ipandport;
|
||||
struct socket_address addr;
|
||||
sid_t peer_sid;
|
||||
|
||||
int priority;
|
||||
@ -50,7 +50,7 @@ struct rhizome_fetch_slot {
|
||||
struct sched_ent alarm; // must be first element in struct
|
||||
rhizome_manifest *manifest;
|
||||
|
||||
struct sockaddr_in peer_ipandport;
|
||||
struct socket_address addr;
|
||||
sid_t peer_sid;
|
||||
|
||||
int state;
|
||||
@ -593,34 +593,25 @@ schedule_fetch(struct rhizome_fetch_slot *slot)
|
||||
slot->alarm.function = rhizome_fetch_poll;
|
||||
slot->alarm.stats = &fetch_stats;
|
||||
|
||||
if (slot->peer_ipandport.sin_family == AF_INET && slot->peer_ipandport.sin_port) {
|
||||
if (slot->addr.addr.sa_family == AF_INET && slot->addr.inet.sin_port) {
|
||||
/* Transfer via HTTP over IPv4 */
|
||||
if ((sock = esocket(AF_INET, SOCK_STREAM, 0)) == -1)
|
||||
goto bail_http;
|
||||
if (set_nonblock(sock) == -1)
|
||||
goto bail_http;
|
||||
char buf[INET_ADDRSTRLEN];
|
||||
if (inet_ntop(AF_INET, &slot->peer_ipandport.sin_addr, buf, sizeof buf) == NULL) {
|
||||
buf[0] = '*';
|
||||
buf[1] = '\0';
|
||||
}
|
||||
if (connect(sock, (struct sockaddr*)&slot->peer_ipandport,
|
||||
sizeof slot->peer_ipandport) == -1) {
|
||||
if (connect(sock, &slot->addr.addr, slot->addr.addrlen) == -1) {
|
||||
if (errno == EINPROGRESS) {
|
||||
if (config.debug.rhizome_rx)
|
||||
DEBUGF("connect() returned EINPROGRESS");
|
||||
} else {
|
||||
WHYF_perror("connect(%d, %s:%u)", sock, buf,
|
||||
ntohs(slot->peer_ipandport.sin_port));
|
||||
WHYF_perror("connect(%d, %s)", sock, alloca_socket_address(&slot->addr));
|
||||
goto bail_http;
|
||||
}
|
||||
}
|
||||
if (config.debug.rhizome_rx)
|
||||
DEBUGF("RHIZOME HTTP REQUEST family=%u addr=%s sid=%s port=%u %s",
|
||||
slot->peer_ipandport.sin_family,
|
||||
buf,
|
||||
DEBUGF("RHIZOME HTTP REQUEST addr=%s sid=%s %s",
|
||||
alloca_socket_address(&slot->addr),
|
||||
alloca_tohex_sid_t(slot->peer_sid),
|
||||
ntohs(slot->peer_ipandport.sin_port),
|
||||
alloca_str_toprint(slot->request)
|
||||
);
|
||||
slot->alarm.poll.fd = sock;
|
||||
@ -684,7 +675,8 @@ schedule_fetch(struct rhizome_fetch_slot *slot)
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
static enum rhizome_start_fetch_result
|
||||
rhizome_fetch(struct rhizome_fetch_slot *slot, rhizome_manifest *m, const struct sockaddr_in *peerip, const sid_t *peersidp)
|
||||
rhizome_fetch(struct rhizome_fetch_slot *slot, rhizome_manifest *m,
|
||||
const struct socket_address *addr, const sid_t *peersidp)
|
||||
{
|
||||
IN();
|
||||
if (slot->state != RHIZOME_FETCH_FREE)
|
||||
@ -705,12 +697,12 @@ rhizome_fetch(struct rhizome_fetch_slot *slot, rhizome_manifest *m, const struct
|
||||
*/
|
||||
|
||||
if (config.debug.rhizome_rx)
|
||||
DEBUGF("Fetching bundle slot=%d bid=%s version=%"PRIu64" size=%"PRIu64" peerip=%s",
|
||||
DEBUGF("Fetching bundle slot=%d bid=%s version=%"PRIu64" size=%"PRIu64" addr=%s",
|
||||
slotno(slot),
|
||||
alloca_tohex_rhizome_bid_t(m->cryptoSignPublic),
|
||||
m->version,
|
||||
m->filesize,
|
||||
alloca_sockaddr(peerip, sizeof(struct sockaddr_in))
|
||||
alloca_socket_address(addr)
|
||||
);
|
||||
|
||||
// If the payload is empty, no need to fetch, so import now.
|
||||
@ -767,7 +759,7 @@ rhizome_fetch(struct rhizome_fetch_slot *slot, rhizome_manifest *m, const struct
|
||||
DEBUGF(" is new");
|
||||
|
||||
/* Prepare for fetching */
|
||||
slot->peer_ipandport = *peerip;
|
||||
slot->addr = *addr;
|
||||
slot->peer_sid = *peersidp;
|
||||
slot->manifest = m;
|
||||
|
||||
@ -787,17 +779,17 @@ rhizome_fetch(struct rhizome_fetch_slot *slot, rhizome_manifest *m, const struct
|
||||
* Returns -1 on error.
|
||||
*/
|
||||
enum rhizome_start_fetch_result
|
||||
rhizome_fetch_request_manifest_by_prefix(const struct sockaddr_in *peerip,
|
||||
rhizome_fetch_request_manifest_by_prefix(const struct socket_address *addr,
|
||||
const sid_t *peersidp,
|
||||
const unsigned char *prefix, size_t prefix_length)
|
||||
{
|
||||
assert(peerip);
|
||||
assert(addr);
|
||||
struct rhizome_fetch_slot *slot = rhizome_find_fetch_slot(MAX_MANIFEST_BYTES);
|
||||
if (slot == NULL)
|
||||
return SLOTBUSY;
|
||||
|
||||
/* Prepare for fetching via HTTP */
|
||||
slot->peer_ipandport = *peerip;
|
||||
slot->addr = *addr;
|
||||
slot->manifest = NULL;
|
||||
slot->peer_sid = *peersidp;
|
||||
bcopy(prefix, slot->bid.binary, prefix_length);
|
||||
@ -824,7 +816,7 @@ static void rhizome_start_next_queued_fetch(struct rhizome_fetch_slot *slot)
|
||||
unsigned i = 0;
|
||||
struct rhizome_fetch_candidate *c;
|
||||
while (i < q->candidate_queue_size && (c = &q->candidate_queue[i])->manifest) {
|
||||
int result = rhizome_fetch(slot, c->manifest, &c->peer_ipandport, &c->peer_sid);
|
||||
int result = rhizome_fetch(slot, c->manifest, &c->addr, &c->peer_sid);
|
||||
switch (result) {
|
||||
case SLOTBUSY:
|
||||
OUT(); return;
|
||||
@ -880,7 +872,7 @@ int rhizome_fetch_has_queue_space(unsigned char log2_size){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Queue a fetch for the payload of the given manifest. If 'peerip' is not NULL, then it is used as
|
||||
/* Queue a fetch for the payload of the given manifest. If 'addr' is not NULL, then it is used as
|
||||
* the port and IP address of an HTTP server from which the fetch is performed. Otherwise the fetch
|
||||
* is performed over MDP.
|
||||
*
|
||||
@ -897,7 +889,7 @@ int rhizome_fetch_has_queue_space(unsigned char log2_size){
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
int rhizome_suggest_queue_manifest_import(rhizome_manifest *m, const struct sockaddr_in *peerip, const sid_t *peersidp)
|
||||
int rhizome_suggest_queue_manifest_import(rhizome_manifest *m, const struct socket_address *addr, const sid_t *peersidp)
|
||||
{
|
||||
IN();
|
||||
|
||||
@ -1000,7 +992,7 @@ int rhizome_suggest_queue_manifest_import(rhizome_manifest *m, const struct sock
|
||||
struct rhizome_fetch_candidate *c = rhizome_fetch_insert(qi, ci);
|
||||
c->manifest = m;
|
||||
c->priority = priority;
|
||||
c->peer_ipandport = *peerip;
|
||||
c->addr = *addr;
|
||||
c->peer_sid = *peersidp;
|
||||
|
||||
if (config.debug.rhizome_rx) {
|
||||
@ -1332,13 +1324,8 @@ static int rhizome_write_complete(struct rhizome_fetch_slot *slot)
|
||||
}
|
||||
|
||||
if (slot->state==RHIZOME_FETCH_RXFILE) {
|
||||
char buf[INET_ADDRSTRLEN];
|
||||
if (inet_ntop(AF_INET, &slot->peer_ipandport.sin_addr, buf, sizeof buf) == NULL) {
|
||||
buf[0] = '*';
|
||||
buf[1] = '\0';
|
||||
}
|
||||
INFOF("Completed http request from %s:%u for file %s",
|
||||
buf, ntohs(slot->peer_ipandport.sin_port),
|
||||
INFOF("Completed http request from %s for file %s",
|
||||
alloca_socket_address(&slot->addr),
|
||||
alloca_tohex_rhizome_filehash_t(slot->manifest->filehash));
|
||||
} else {
|
||||
INFOF("Completed MDP request from %s for file %s",
|
||||
@ -1362,11 +1349,12 @@ static int rhizome_write_complete(struct rhizome_fetch_slot *slot)
|
||||
rhizome_manifest_free(m);
|
||||
} else {
|
||||
if (config.debug.rhizome_rx){
|
||||
DEBUGF("All looks good for importing manifest id=%s", alloca_tohex_rhizome_bid_t(m->cryptoSignPublic));
|
||||
dump("slot->peerip",&slot->peer_ipandport,sizeof(slot->peer_ipandport));
|
||||
dump("slot->peersid",&slot->peer_sid,sizeof(slot->peer_sid));
|
||||
DEBUGF("All looks good for importing manifest id=%s, addr=%s, sid=%s",
|
||||
alloca_tohex_rhizome_bid_t(m->cryptoSignPublic),
|
||||
alloca_socket_address(&slot->addr),
|
||||
alloca_tohex_sid_t(slot->peer_sid));
|
||||
}
|
||||
rhizome_suggest_queue_manifest_import(m, &slot->peer_ipandport, &slot->peer_sid);
|
||||
rhizome_suggest_queue_manifest_import(m, &slot->addr, &slot->peer_sid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "rhizome.h"
|
||||
#include "dataformats.h"
|
||||
#include "http_server.h"
|
||||
#include "overlay_interface.h"
|
||||
|
||||
#define RHIZOME_SERVER_MAX_LIVE_REQUESTS 32
|
||||
|
||||
|
@ -290,14 +290,17 @@ int overlay_rhizome_saw_advertisements(struct decode_context *context, struct ov
|
||||
RETURN(0);
|
||||
|
||||
int ad_frame_type=ob_get(f->payload);
|
||||
struct sockaddr_in httpaddr = context->addr;
|
||||
httpaddr.sin_port = htons(RHIZOME_HTTP_PORT);
|
||||
struct socket_address httpaddr = context->addr;
|
||||
if (httpaddr.addr.sa_family == AF_INET)
|
||||
httpaddr.inet.sin_port = htons(RHIZOME_HTTP_PORT);
|
||||
rhizome_manifest *m=NULL;
|
||||
|
||||
int (*oldfunc)() = sqlite_set_tracefunc(is_debug_rhizome_ads);
|
||||
|
||||
if (ad_frame_type & HAS_PORT){
|
||||
httpaddr.sin_port = htons(ob_get_ui16(f->payload));
|
||||
uint16_t port = ob_get_ui16(f->payload);
|
||||
if (httpaddr.addr.sa_family == AF_INET)
|
||||
httpaddr.inet.sin_port = htons(port);
|
||||
}
|
||||
|
||||
if (ad_frame_type & HAS_MANIFESTS){
|
||||
|
29
route_link.c
29
route_link.c
@ -20,6 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "serval.h"
|
||||
#include "overlay_address.h"
|
||||
#include "overlay_buffer.h"
|
||||
#include "overlay_interface.h"
|
||||
#include "overlay_packet.h"
|
||||
#include "str.h"
|
||||
#include "conf.h"
|
||||
@ -189,9 +190,9 @@ struct network_destination * new_destination(struct overlay_interface *interface
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct network_destination * create_unicast_destination(struct sockaddr_in addr, struct overlay_interface *interface){
|
||||
if (!interface)
|
||||
interface = overlay_interface_find(addr.sin_addr, 1);
|
||||
struct network_destination * create_unicast_destination(struct socket_address *addr, struct overlay_interface *interface){
|
||||
if (!interface && addr->addr.sa_family == AF_INET)
|
||||
interface = overlay_interface_find(addr->inet.sin_addr, 1);
|
||||
if (!interface){
|
||||
WHY("I don't know which interface to use");
|
||||
return NULL;
|
||||
@ -200,14 +201,12 @@ struct network_destination * create_unicast_destination(struct sockaddr_in addr,
|
||||
WHY("The interface is down.");
|
||||
return NULL;
|
||||
}
|
||||
if (addr.sin_addr.s_addr==0 || addr.sin_port==0){
|
||||
// WHY("Invalid unicast address");
|
||||
if (addr->addr.sa_family == AF_INET && (addr->inet.sin_addr.s_addr==0 || addr->inet.sin_port==0))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct network_destination *ret = new_destination(interface, ENCAP_OVERLAY);
|
||||
if (ret){
|
||||
ret->address = addr;
|
||||
ret->address = *addr;
|
||||
ret->unicast = 1;
|
||||
ret->tick_ms = interface->destination->tick_ms;
|
||||
ret->sequence_number = -1;
|
||||
@ -1107,20 +1106,20 @@ int link_received_duplicate(struct subscriber *subscriber, int payload_seq)
|
||||
}
|
||||
|
||||
// remote peer has confirmed hearing a recent unicast packet
|
||||
int link_unicast_ack(struct subscriber *UNUSED(subscriber), struct overlay_interface *UNUSED(interface), struct sockaddr_in UNUSED(addr))
|
||||
int link_unicast_ack(struct subscriber *UNUSED(subscriber), struct overlay_interface *UNUSED(interface), struct socket_address *UNUSED(addr))
|
||||
{
|
||||
// TODO find / create network destination, keep it alive
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct link_out *create_out_link(struct neighbour *neighbour, overlay_interface *interface, struct sockaddr_in *addr, char unicast)
|
||||
static struct link_out *create_out_link(struct neighbour *neighbour, overlay_interface *interface, struct socket_address *addr, char unicast)
|
||||
{
|
||||
struct link_out *ret=emalloc_zero(sizeof(struct link_out));
|
||||
if (ret){
|
||||
ret->_next=neighbour->out_links;
|
||||
neighbour->out_links=ret;
|
||||
if (unicast)
|
||||
ret->destination = create_unicast_destination(*addr, interface);
|
||||
ret->destination = create_unicast_destination(addr, interface);
|
||||
else
|
||||
ret->destination = add_destination_ref(interface->destination);
|
||||
if (config.debug.linkstate)
|
||||
@ -1135,7 +1134,7 @@ static struct link_out *create_out_link(struct neighbour *neighbour, overlay_int
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void create_out_links(struct neighbour *neighbour, overlay_interface *interface, struct sockaddr_in *addr){
|
||||
static void create_out_links(struct neighbour *neighbour, overlay_interface *interface, struct socket_address *addr){
|
||||
struct link_out *l = neighbour->out_links;
|
||||
while(l){
|
||||
if (l->destination->interface==interface)
|
||||
@ -1143,13 +1142,13 @@ static void create_out_links(struct neighbour *neighbour, overlay_interface *int
|
||||
l=l->_next;
|
||||
}
|
||||
// if this packet arrived in an IPv4 packet, assume we need to send them unicast packets
|
||||
if (addr && addr->sin_family==AF_INET && addr->sin_port!=0 && addr->sin_addr.s_addr!=0)
|
||||
if (addr && addr->addr.sa_family==AF_INET && addr->inet.sin_port!=0 && addr->inet.sin_addr.s_addr!=0)
|
||||
create_out_link(neighbour, interface, addr, 1);
|
||||
|
||||
// if this packet arrived from the same IPv4 subnet, or a different type of network, assume they can hear our broadcasts
|
||||
if (!addr || addr->sin_family!=AF_INET ||
|
||||
(addr->sin_addr.s_addr & interface->netmask.s_addr)
|
||||
== (interface->address.sin_addr.s_addr & interface->netmask.s_addr))
|
||||
if (!addr || addr->addr.sa_family!=AF_INET ||
|
||||
(addr->inet.sin_addr.s_addr & interface->netmask.s_addr)
|
||||
== (interface->address.inet.sin_addr.s_addr & interface->netmask.s_addr))
|
||||
create_out_link(neighbour, interface, addr, 0);
|
||||
}
|
||||
|
||||
|
195
serval.h
195
serval.h
@ -244,12 +244,12 @@ extern char *batman_peerfile;
|
||||
struct subscriber;
|
||||
struct decode_context;
|
||||
struct socket_address;
|
||||
struct overlay_interface;
|
||||
struct network_destination;
|
||||
|
||||
/* Make sure we have space to put bytes of the packet as we go along */
|
||||
#define CHECK_PACKET_LEN(B) {if (((*packet_len)+(B))>=packet_maxlen) { return WHY("Packet composition ran out of space."); } }
|
||||
|
||||
extern int sock;
|
||||
|
||||
struct limit_state{
|
||||
// length of time for a burst
|
||||
time_ms_t burst_length;
|
||||
@ -270,11 +270,6 @@ struct broadcast;
|
||||
|
||||
extern int overlayMode;
|
||||
|
||||
#define INTERFACE_STATE_FREE 0
|
||||
#define INTERFACE_STATE_UP 1
|
||||
#define INTERFACE_STATE_DOWN 2
|
||||
#define INTERFACE_STATE_DETECTING 3
|
||||
|
||||
// Specify the size of the receive buffer.
|
||||
// This effectively sets the MRU for packet radio interfaces
|
||||
// where we have to buffer packets on the receive side
|
||||
@ -305,123 +300,6 @@ struct slip_decode_state{
|
||||
unsigned dst_offset;
|
||||
};
|
||||
|
||||
struct overlay_interface;
|
||||
|
||||
// where should packets be sent to?
|
||||
struct network_destination {
|
||||
int _ref_count;
|
||||
|
||||
// which interface are we actually sending packets out of
|
||||
struct overlay_interface *interface;
|
||||
|
||||
// The IPv4 destination address, this may be the interface broadcast address.
|
||||
struct sockaddr_in address;
|
||||
|
||||
// should outgoing packets be marked as unicast?
|
||||
char unicast;
|
||||
|
||||
char packet_version;
|
||||
|
||||
// should we aggregate packets, or send one at a time
|
||||
char encapsulation;
|
||||
|
||||
// time last packet was sent
|
||||
time_ms_t last_tx;
|
||||
|
||||
int min_rtt;
|
||||
int max_rtt;
|
||||
int resend_delay;
|
||||
|
||||
// sequence number of last packet sent to this destination.
|
||||
// Used to allow NACKs that can request retransmission of recent packets.
|
||||
int sequence_number;
|
||||
|
||||
// rate limit for outgoing packets
|
||||
struct limit_state transfer_limit;
|
||||
|
||||
/* Number of milli-seconds per tick for this interface, which is basically
|
||||
* related to the the typical TX range divided by the maximum expected
|
||||
* speed of nodes in the network. This means that short-range communications
|
||||
* has a higher bandwidth requirement than long-range communications because
|
||||
* the tick interval has to be shorter to still allow fast-convergence time
|
||||
* to allow for mobility.
|
||||
*
|
||||
* For wifi (nominal range 100m) it is usually 500ms.
|
||||
* For ~100K ISM915MHz (nominal range 1000m) it will probably be about 5000ms.
|
||||
* For ~10K ISM915MHz (nominal range ~3000m) it will probably be about 15000ms.
|
||||
*
|
||||
* These figures will be refined over time, and we will allow people to set
|
||||
* them per-interface.
|
||||
*/
|
||||
unsigned tick_ms;
|
||||
|
||||
// Number of milliseconds of no packets until we assume the link is dead.
|
||||
unsigned reachable_timeout_ms;
|
||||
};
|
||||
|
||||
struct network_destination * new_destination(struct overlay_interface *interface, char encapsulation);
|
||||
struct network_destination * create_unicast_destination(struct sockaddr_in addr, struct overlay_interface *interface);
|
||||
struct network_destination * add_destination_ref(struct network_destination *ref);
|
||||
void release_destination_ref(struct network_destination *ref);
|
||||
int set_destination_ref(struct network_destination **ptr, struct network_destination *ref);
|
||||
|
||||
typedef struct overlay_interface {
|
||||
struct sched_ent alarm;
|
||||
|
||||
char name[256];
|
||||
|
||||
int recv_offset; /* file offset */
|
||||
|
||||
int recv_count;
|
||||
int tx_count;
|
||||
|
||||
struct radio_link_state *radio_link_state;
|
||||
|
||||
// copy of ifconfig flags
|
||||
uint16_t drop_packets;
|
||||
char drop_broadcasts;
|
||||
char drop_unicasts;
|
||||
int port;
|
||||
int type;
|
||||
int socket_type;
|
||||
char send_broadcasts;
|
||||
char prefer_unicast;
|
||||
/* Not necessarily the real MTU, but the largest frame size we are willing to TX.
|
||||
For radio links the actual maximum and the maximum that is likely to be delivered reliably are
|
||||
potentially two quite different values. */
|
||||
int mtu;
|
||||
// can we use this interface for routes to addresses in other subnets?
|
||||
int default_route;
|
||||
// should we log more debug info on this interace? eg hex dumps of packets
|
||||
char debug;
|
||||
char local_echo;
|
||||
|
||||
unsigned int uartbps; // set serial port speed (which might be different from link speed)
|
||||
int ctsrts; // enabled hardware flow control if non-zero
|
||||
|
||||
struct network_destination *destination;
|
||||
|
||||
// can we assume that we will only receive packets from one device?
|
||||
char point_to_point;
|
||||
struct subscriber *other_device;
|
||||
|
||||
// the actual address of the interface.
|
||||
struct sockaddr_in address;
|
||||
struct in_addr netmask;
|
||||
|
||||
/* Use one of the INTERFACE_STATE_* constants to indicate the state of this interface.
|
||||
If the interface stops working or disappears, it will be marked as DOWN and the socket closed.
|
||||
But if it comes back up again, we should try to reuse this structure, even if the broadcast address has changed.
|
||||
*/
|
||||
int state;
|
||||
} overlay_interface;
|
||||
|
||||
/* Maximum interface count is rather arbitrary.
|
||||
Memory consumption is O(n) with respect to this parameter, so let's not make it too big for now.
|
||||
*/
|
||||
extern overlay_interface overlay_interfaces[OVERLAY_MAX_INTERFACES];
|
||||
extern int overlay_last_interface_number; // used to remember where a packet came from
|
||||
extern unsigned int overlay_sequence_number;
|
||||
|
||||
int server_pid();
|
||||
void server_save_argv(int argc, const char *const *argv);
|
||||
@ -439,14 +317,11 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
|
||||
int parseMdpPacketHeader(struct decode_context *context, struct overlay_frame *frame,
|
||||
struct overlay_buffer *buffer, struct subscriber **nexthop);
|
||||
int parseEnvelopeHeader(struct decode_context *context, struct overlay_interface *interface,
|
||||
struct sockaddr_in *addr, struct overlay_buffer *buffer);
|
||||
struct socket_address *addr, struct overlay_buffer *buffer);
|
||||
int process_incoming_frame(time_ms_t now, struct overlay_interface *interface,
|
||||
struct overlay_frame *f, struct decode_context *context);
|
||||
|
||||
int overlay_frame_process(struct overlay_interface *interface, struct overlay_frame *f);
|
||||
int overlay_frame_resolve_addresses(struct overlay_frame *f);
|
||||
|
||||
time_ms_t overlay_time_until_next_tick();
|
||||
|
||||
int overlay_frame_append_payload(struct decode_context *context, int encapsulation,
|
||||
struct overlay_frame *p, struct overlay_buffer *b,
|
||||
@ -454,20 +329,9 @@ int overlay_frame_append_payload(struct decode_context *context, int encapsulati
|
||||
int overlay_packet_init_header(int packet_version, int encapsulation,
|
||||
struct decode_context *context, struct overlay_buffer *buff,
|
||||
char unicast, char interface, int seq);
|
||||
int overlay_interface_args(const char *arg);
|
||||
void overlay_rhizome_advertise(struct sched_ent *alarm);
|
||||
void rhizome_sync_status_html(struct strbuf *b, struct subscriber *subscriber);
|
||||
int rhizome_cache_count();
|
||||
int overlay_add_local_identity(unsigned char *s);
|
||||
|
||||
extern unsigned overlay_interface_count;
|
||||
|
||||
extern int overlay_local_identity_count;
|
||||
extern unsigned char *overlay_local_identities[OVERLAY_MAX_LOCAL_IDENTITIES];
|
||||
|
||||
int rfs_length(int l);
|
||||
int rfs_encode(int l,unsigned char *b);
|
||||
int rfs_decode(unsigned char *b,int *offset);
|
||||
|
||||
int overlayServerMode(const struct cli_parsed *parsed);
|
||||
int overlay_payload_enqueue(struct overlay_frame *p);
|
||||
@ -477,7 +341,6 @@ int overlay_send_tick_packet(struct network_destination *destination);
|
||||
int overlay_queue_ack(struct subscriber *neighbour, struct network_destination *destination, uint32_t ack_mask, int ack_seq);
|
||||
|
||||
int overlay_rhizome_saw_advertisements(struct decode_context *context, struct overlay_frame *f);
|
||||
int rhizome_server_get_fds(struct pollfd *fds,int *fdcount,int fdmax);
|
||||
int rhizome_saw_voice_traffic();
|
||||
int overlay_saw_mdp_containing_frame(struct overlay_frame *f);
|
||||
|
||||
@ -486,13 +349,10 @@ int serval_packetvisualise_xpf(XPRINTF xpf, const char *message, const unsigned
|
||||
void logServalPacket(int level, struct __sourceloc __whence, const char *message, const unsigned char *packet, size_t len);
|
||||
#define DEBUG_packet_visualise(M,P,N) logServalPacket(LOG_LEVEL_DEBUG, __WHENCE__, (M), (P), (N))
|
||||
|
||||
int rhizome_fetching_get_fds(struct pollfd *fds,int *fdcount,int fdmax);
|
||||
int rhizome_opendb();
|
||||
|
||||
int parseCommandLine(struct cli_context *context, const char *argv0, int argc, const char *const *argv);
|
||||
|
||||
int overlay_mdp_get_fds(struct pollfd *fds,int *fdcount,int fdmax);
|
||||
|
||||
typedef uint32_t mdp_port_t;
|
||||
#define PRImdp_port_t "#08" PRIx32
|
||||
|
||||
@ -567,7 +427,6 @@ int mdp_unbind_internal(struct subscriber *subscriber, mdp_port_t port,
|
||||
struct vomp_call_state;
|
||||
|
||||
void set_codec_flag(int codec, unsigned char *flags);
|
||||
int is_codec_set(int codec, unsigned char *flags);
|
||||
|
||||
struct vomp_call_state *vomp_find_call_by_session(unsigned int session_token);
|
||||
int vomp_mdp_received(overlay_mdp_frame *mdp);
|
||||
@ -580,17 +439,6 @@ int vomp_received_audio(struct vomp_call_state *call, int audio_codec, int time,
|
||||
const unsigned char *audio, int audio_length);
|
||||
void monitor_get_all_supported_codecs(unsigned char *codecs);
|
||||
|
||||
int overlay_route_node_info(overlay_mdp_nodeinfo *node_info);
|
||||
int overlay_interface_register(char *name,
|
||||
struct in_addr addr,
|
||||
struct in_addr mask);
|
||||
overlay_interface * overlay_interface_get_default();
|
||||
overlay_interface * overlay_interface_find(struct in_addr addr, int return_default);
|
||||
overlay_interface * overlay_interface_find_name(const char *name);
|
||||
int overlay_interface_compare(overlay_interface *one, overlay_interface *two);
|
||||
int overlay_broadcast_ensemble(struct network_destination *destination, struct overlay_buffer *buffer);
|
||||
void interface_state_html(struct strbuf *b, struct overlay_interface *interface);
|
||||
|
||||
int directory_registration();
|
||||
int directory_service_init();
|
||||
|
||||
@ -616,37 +464,9 @@ int monitor_tell_formatted(int mask, char *fmt, ...);
|
||||
int monitor_client_interested(int mask);
|
||||
extern int monitor_socket_count;
|
||||
|
||||
|
||||
typedef struct monitor_audio {
|
||||
char name[128];
|
||||
int (*start)();
|
||||
int (*stop)();
|
||||
int (*poll_fds)(struct pollfd *,int);
|
||||
int (*read)(unsigned char *,int);
|
||||
int (*write)(unsigned char *,int);
|
||||
} monitor_audio;
|
||||
extern monitor_audio *audev;
|
||||
|
||||
monitor_audio *audio_msm_g1_detect();
|
||||
monitor_audio *audio_alsa_detect();
|
||||
monitor_audio *audio_reflector_detect();
|
||||
int detectAudioDevice();
|
||||
int getAudioPlayFd();
|
||||
int getAudioRecordFd();
|
||||
int getAudioBytes(unsigned char *buffer,
|
||||
int offset,
|
||||
int bufferSize);
|
||||
int encodeAndDispatchRecordedAudio(int fd,int callSessionToken,
|
||||
int recordCodec,
|
||||
unsigned char *sampleData,
|
||||
int sampleBytes);
|
||||
int scrapeProcNetRoute();
|
||||
int lsif();
|
||||
int doifaddrs();
|
||||
int bufferAudioForPlayback(int codec, time_ms_t start_time, time_ms_t end_time,
|
||||
unsigned char *data,int dataLen);
|
||||
int startAudio();
|
||||
int stopAudio();
|
||||
|
||||
#define SERVER_UNKNOWN 1
|
||||
#define SERVER_NOTRESPONDING 2
|
||||
@ -667,11 +487,7 @@ void sigIoHandler(int signal);
|
||||
|
||||
int overlay_mdp_setup_sockets();
|
||||
|
||||
void overlay_interface_discover(struct sched_ent *alarm);
|
||||
void overlay_packetradio_poll(struct sched_ent *alarm);
|
||||
int overlay_packetradio_setup_port(overlay_interface *interface);
|
||||
int overlay_packetradio_tx_packet(struct overlay_frame *frame);
|
||||
void overlay_dummy_poll(struct sched_ent *alarm);
|
||||
int overlay_packetradio_setup_port(struct overlay_interface *interface);
|
||||
void server_config_reload(struct sched_ent *alarm);
|
||||
void server_shutdown_check(struct sched_ent *alarm);
|
||||
int overlay_mdp_try_internal_services(struct overlay_frame *frame, overlay_mdp_frame *mdp);
|
||||
@ -680,7 +496,6 @@ int overlay_send_stun_request(struct subscriber *server, struct subscriber *requ
|
||||
void fd_periodicstats(struct sched_ent *alarm);
|
||||
void rhizome_check_connections(struct sched_ent *alarm);
|
||||
|
||||
int overlay_tick_interface(int i, time_ms_t now);
|
||||
int overlay_queue_init();
|
||||
|
||||
void monitor_client_poll(struct sched_ent *alarm);
|
||||
@ -722,7 +537,7 @@ int link_state_announce_links();
|
||||
int link_state_legacy_ack(struct overlay_frame *frame, time_ms_t now);
|
||||
int link_state_ack_soon(struct subscriber *sender);
|
||||
int link_state_should_forward_broadcast(struct subscriber *transmitter);
|
||||
int link_unicast_ack(struct subscriber *subscriber, struct overlay_interface *interface, struct sockaddr_in addr);
|
||||
int link_unicast_ack(struct subscriber *subscriber, struct overlay_interface *interface, struct socket_address *addr);
|
||||
int link_add_destinations(struct overlay_frame *frame);
|
||||
void link_neighbour_short_status_html(struct strbuf *b, const char *link_prefix);
|
||||
void link_neighbour_status_html(struct strbuf *b, struct subscriber *neighbour);
|
||||
|
1
server.c
1
server.c
@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "conf.h"
|
||||
#include "strbuf.h"
|
||||
#include "strbuf_helpers.h"
|
||||
#include "overlay_interface.h"
|
||||
|
||||
#define PIDFILE_NAME "servald.pid"
|
||||
#define STOPFILE_NAME "servald.stop"
|
||||
|
20
socket.c
20
socket.c
@ -164,6 +164,7 @@ int cmp_sockaddr(const struct socket_address *addrA, const struct socket_address
|
||||
(addrA->addrlen < addrB->addrlen ? addrA->addrlen : addrB->addrlen) - sizeof addrA->addr.sa_family);
|
||||
if (c == 0)
|
||||
c = addrA->addrlen < addrB->addrlen ? -1 : addrA->addrlen > addrB->addrlen ? 1 : 0;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
@ -234,6 +235,24 @@ int _socket_set_rcvbufsize(struct __sourceloc __whence, int sock, unsigned buffe
|
||||
return 0;
|
||||
}
|
||||
|
||||
int socket_unlink_close(int sock)
|
||||
{
|
||||
// get the socket name and unlink it from the filesystem if not abstract
|
||||
struct socket_address addr;
|
||||
addr.addrlen = sizeof addr.store;
|
||||
if (getsockname(sock, &addr.addr, &addr.addrlen))
|
||||
WHYF_perror("getsockname(%d)", sock);
|
||||
else if (addr.addr.sa_family==AF_UNIX
|
||||
&& addr.addrlen > sizeof addr.local.sun_family
|
||||
&& addr.addrlen <= sizeof addr.local
|
||||
&& addr.local.sun_path[0] != '\0') {
|
||||
if (unlink(addr.local.sun_path) == -1)
|
||||
WARNF_perror("unlink(%s)", alloca_str_toprint(addr.local.sun_path));
|
||||
}
|
||||
close(sock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t _send_message(struct __sourceloc __whence, int fd, const struct socket_address *address, const struct fragmented_data *data)
|
||||
{
|
||||
struct msghdr hdr={
|
||||
@ -260,5 +279,6 @@ ssize_t _recv_message(struct __sourceloc __whence, int fd, struct socket_address
|
||||
ssize_t ret = recvmsg(fd, &hdr, 0);
|
||||
if (ret==-1)
|
||||
WHYF_perror("recvmsg(%d,%s,%lu)", fd, alloca_socket_address(address), (unsigned long)address->addrlen);
|
||||
address->addrlen = hdr.msg_namelen;
|
||||
return ret;
|
||||
}
|
||||
|
1
socket.h
1
socket.h
@ -54,6 +54,7 @@ int _socket_connect(struct __sourceloc, int sock, const struct sockaddr *addr, s
|
||||
int _socket_listen(struct __sourceloc, int sock, int backlog);
|
||||
int _socket_set_reuseaddr(struct __sourceloc, int sock, int reuseP);
|
||||
int _socket_set_rcvbufsize(struct __sourceloc, int sock, unsigned buffer_size);
|
||||
int socket_unlink_close(int sock);
|
||||
|
||||
#define make_local_sockaddr(sockname, fmt,...) _make_local_sockaddr(__WHENCE__, (sockname), (fmt), ##__VA_ARGS__)
|
||||
#define esocket(domain, type, protocol) _esocket(__WHENCE__, (domain), (type), (protocol))
|
||||
|
Loading…
Reference in New Issue
Block a user