Refactor interface addresses to use new socket_address struct

This commit is contained in:
Jeremy Lakeman 2013-12-09 17:45:47 +10:30
parent df6af96455
commit 5f2c6e364a
29 changed files with 444 additions and 491 deletions

View File

@ -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"

View File

@ -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 \

View File

@ -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"

52
lsif.c
View File

@ -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,7 +136,10 @@ 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");
@ -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;
@ -159,7 +175,8 @@ lsif(void) {
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;
netmask = ((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;
addr.addrlen = sizeof(addr.inet);
bcopy(ifa->ifa_addr, &addr.addr, addr.addrlen);
overlay_interface_register(name, addr, netmask);
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, &broadcast);
}
freeifaddrs(ifaddr);

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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,17 +112,27 @@ 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)");
goto error;
@ -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.
@ -959,48 +919,31 @@ overlay_interface_register(char *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;
if (strcasecmp(overlay_interfaces[i].name, name)
&& cmp_sockaddr(addr, &overlay_interfaces[i].address)==0
&& overlay_interfaces[i].state!=INTERFACE_STATE_DOWN){
name_match = !strcasecmp(overlay_interfaces[i].name, name);
// if we find an exact match we can stop searching
if (name_match && broadcast_match){
// 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
View 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

View File

@ -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);

View File

@ -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;

View File

@ -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"

View File

@ -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

View File

@ -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);

View File

@ -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)
{

View File

@ -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"

View File

@ -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)
{

View File

@ -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"

View File

@ -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);

View File

@ -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;

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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){

View File

@ -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
View File

@ -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);

View File

@ -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"

View File

@ -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;
}

View File

@ -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))