2010-07-13 12:15:46 +00:00
|
|
|
/*
|
|
|
|
Serval Distributed Numbering Architecture (DNA)
|
|
|
|
Copyright (C) 2010 Paul Gardner-Stephen
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
2012-07-23 04:17:59 +00:00
|
|
|
|
2012-04-20 09:56:08 +00:00
|
|
|
// #define MALLOC_PARANOIA
|
2012-04-20 06:11:13 +00:00
|
|
|
|
2010-07-13 12:15:46 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <stdlib.h>
|
2012-05-10 03:23:57 +00:00
|
|
|
#include <stdarg.h>
|
2010-07-13 12:15:46 +00:00
|
|
|
#ifdef HAVE_STRINGS_H
|
|
|
|
#include <strings.h>
|
|
|
|
#endif
|
|
|
|
#include <string.h>
|
2011-12-01 19:14:32 +00:00
|
|
|
#include <signal.h>
|
2012-05-14 09:02:10 +00:00
|
|
|
#include <sys/types.h>
|
2011-03-30 05:04:23 +00:00
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
#include "win32/win32.h"
|
|
|
|
#else
|
|
|
|
#include <unistd.h>
|
2011-10-16 21:41:05 +00:00
|
|
|
#ifdef HAVE_SYS_SOCKET_H
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_NET_ROUTE_H
|
|
|
|
#include <net/route.h>
|
|
|
|
#endif
|
2012-04-28 11:14:20 +00:00
|
|
|
#ifdef HAVE_LINUX_IF_H
|
|
|
|
#include <linux/if.h>
|
|
|
|
#else
|
2011-07-08 05:06:54 +00:00
|
|
|
#ifdef HAVE_NET_IF_H
|
|
|
|
#include <net/if.h>
|
|
|
|
#endif
|
2012-04-28 11:14:20 +00:00
|
|
|
#endif
|
2011-07-08 05:06:54 +00:00
|
|
|
#ifdef HAVE_NETINET_IN_H
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_LINUX_NETLINK_H
|
|
|
|
#include <linux/netlink.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_LINUX_RTNETLINK_H
|
|
|
|
#include <linux/rtnetlink.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_IFADDRS_H
|
|
|
|
#include <ifaddrs.h>
|
|
|
|
#endif
|
2012-05-21 02:52:50 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_SYS_UCRED_H
|
|
|
|
#include <sys/ucred.h>
|
|
|
|
#endif
|
2011-03-30 05:04:23 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if !defined(FORASTERISK) && !defined(s_addr)
|
2010-07-13 12:15:46 +00:00
|
|
|
#ifdef HAVE_ARPA_INET_H
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
#else
|
|
|
|
typedef unsigned int in_addr_t;
|
|
|
|
struct in_addr {
|
|
|
|
in_addr_t s_addr;
|
|
|
|
};
|
|
|
|
#endif
|
2011-03-21 02:38:35 +00:00
|
|
|
#endif
|
2011-03-30 05:04:23 +00:00
|
|
|
|
2010-07-13 12:15:46 +00:00
|
|
|
#ifdef HAVE_SYS_SOCKET_H
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_SYS_MMAN_H
|
|
|
|
#include <sys/mman.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_SYS_TIME_H
|
|
|
|
#include <sys/time.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_POLL_H
|
|
|
|
#include <poll.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_NETDB_H
|
|
|
|
#include <netdb.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_CTYPE_H
|
|
|
|
#include <ctype.h>
|
|
|
|
#endif
|
2011-03-30 05:04:23 +00:00
|
|
|
|
|
|
|
#ifndef WIN32
|
2010-07-13 12:15:46 +00:00
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <sys/un.h>
|
2011-03-30 05:04:23 +00:00
|
|
|
#endif
|
|
|
|
|
2010-07-13 12:15:46 +00:00
|
|
|
#include <fcntl.h>
|
2011-03-30 05:04:23 +00:00
|
|
|
//FIXME #include <getopt.h>
|
2010-07-13 12:15:46 +00:00
|
|
|
#include <ctype.h>
|
2012-05-10 07:28:25 +00:00
|
|
|
#include <sys/stat.h>
|
2010-07-13 12:15:46 +00:00
|
|
|
|
2012-07-29 03:05:53 +00:00
|
|
|
#include "constants.h"
|
|
|
|
#include "log.h"
|
|
|
|
#include "conf.h"
|
|
|
|
|
2012-02-16 14:33:59 +00:00
|
|
|
|
2012-05-14 09:02:10 +00:00
|
|
|
/* bzero(3) is deprecated in favour of memset(3). */
|
|
|
|
#define bzero(addr,len) memset((addr), 0, (len))
|
|
|
|
|
2011-08-08 14:41:46 +00:00
|
|
|
/* UDP Port numbers for various Serval services.
|
|
|
|
The overlay mesh works over DNA */
|
2011-04-27 11:48:09 +00:00
|
|
|
#define PORT_DNA 4110
|
2010-07-13 12:15:46 +00:00
|
|
|
|
|
|
|
/* OpenWRT libc doesn't have bcopy, but has memmove */
|
|
|
|
#define bcopy(A,B,C) memmove(B,A,C)
|
|
|
|
|
|
|
|
#define BATCH 1
|
|
|
|
#define NONBATCH 0
|
|
|
|
|
|
|
|
#define REQ_SERIAL 0
|
|
|
|
#define REQ_PARALLEL -1
|
|
|
|
#define REQ_FIRSTREPLY -2
|
|
|
|
#define REQ_REPLY -101
|
|
|
|
|
|
|
|
|
|
|
|
#define SET_NOREPLACE 1
|
|
|
|
#define SET_REPLACE 2
|
|
|
|
#define SET_NOCREATE 3
|
|
|
|
#define SET_FRAGMENT 0x80
|
|
|
|
|
|
|
|
#define WITHDATA 1
|
|
|
|
#define WITHOUTDATA 0
|
|
|
|
|
|
|
|
/* Limit packet payloads to minimise packet loss of big packets in mesh networks */
|
|
|
|
#define MAX_DATA_BYTES 256
|
|
|
|
|
2012-05-21 02:50:05 +00:00
|
|
|
extern int dnatimeout;
|
2010-07-13 12:15:46 +00:00
|
|
|
extern int hlr_size;
|
|
|
|
extern unsigned char *hlr;
|
|
|
|
|
|
|
|
double simulatedBER;
|
|
|
|
|
|
|
|
extern int serverMode;
|
2012-03-04 22:57:31 +00:00
|
|
|
extern int servalShutdown;
|
2010-07-13 12:15:46 +00:00
|
|
|
|
2011-12-04 07:18:51 +00:00
|
|
|
extern int returnMultiVars;
|
|
|
|
|
2011-08-10 13:38:59 +00:00
|
|
|
extern char *gatewayspec;
|
2011-05-06 02:27:33 +00:00
|
|
|
|
2012-05-15 03:26:10 +00:00
|
|
|
int rhizome_enabled();
|
2012-07-12 02:40:59 +00:00
|
|
|
int rhizome_http_server_running();
|
2012-05-15 03:26:10 +00:00
|
|
|
const char *rhizome_datastore_path();
|
2011-12-17 01:41:32 +00:00
|
|
|
|
2010-07-13 12:15:46 +00:00
|
|
|
extern struct in_addr client_addr;
|
|
|
|
extern int client_port;
|
|
|
|
|
|
|
|
#define MAX_PEERS 1024
|
|
|
|
extern int peer_count;
|
2011-04-27 11:48:09 +00:00
|
|
|
extern struct in_addr peers[MAX_PEERS];
|
2010-07-13 12:15:46 +00:00
|
|
|
|
|
|
|
struct mphlr_variable {
|
|
|
|
unsigned char id;
|
|
|
|
char *name;
|
|
|
|
char *desc;
|
|
|
|
};
|
|
|
|
|
2012-07-29 03:05:53 +00:00
|
|
|
extern struct mphlr_variable vars[];
|
|
|
|
|
2010-07-13 12:15:46 +00:00
|
|
|
extern char *outputtemplate;
|
2011-05-05 09:10:38 +00:00
|
|
|
extern char *instrumentation_file;
|
2010-07-13 12:15:46 +00:00
|
|
|
extern char *batman_socket;
|
2011-03-21 02:38:35 +00:00
|
|
|
extern char *batman_peerfile;
|
2010-07-13 12:15:46 +00:00
|
|
|
|
2012-04-12 23:55:03 +00:00
|
|
|
|
|
|
|
typedef struct keypair {
|
|
|
|
int type;
|
|
|
|
unsigned char *private_key;
|
|
|
|
int private_key_len;
|
|
|
|
unsigned char *public_key;
|
|
|
|
int public_key_len;
|
|
|
|
} keypair;
|
|
|
|
|
|
|
|
/* Contains just the list of private:public key pairs and types,
|
|
|
|
the pin used to extract them, and the slot in the keyring file
|
|
|
|
(so that it can be replaced/rewritten as required). */
|
|
|
|
#define PKR_MAX_KEYPAIRS 64
|
|
|
|
#define PKR_SALT_BYTES 32
|
|
|
|
#define PKR_MAC_BYTES 64
|
|
|
|
typedef struct keyring_identity {
|
|
|
|
char *PKRPin;
|
|
|
|
unsigned int slot;
|
|
|
|
int keypair_count;
|
|
|
|
keypair *keypairs[PKR_MAX_KEYPAIRS];
|
|
|
|
} keyring_identity;
|
|
|
|
|
|
|
|
/* 64K identities, can easily be increased should the need arise,
|
|
|
|
but keep it low-ish for now so that the 64K pointers don't eat too
|
|
|
|
much ram on a small device. Should probably think about having
|
|
|
|
small and large device settings for some of these things */
|
|
|
|
#define KEYRING_MAX_IDENTITIES 65536
|
|
|
|
typedef struct keyring_context {
|
|
|
|
char *KeyRingPin;
|
|
|
|
unsigned char *KeyRingSalt;
|
|
|
|
int KeyRingSaltLen;
|
|
|
|
|
|
|
|
int identity_count;
|
|
|
|
keyring_identity *identities[KEYRING_MAX_IDENTITIES];
|
|
|
|
} keyring_context;
|
|
|
|
|
|
|
|
#define KEYRING_PAGE_SIZE 4096LL
|
|
|
|
#define KEYRING_BAM_BYTES 2048LL
|
|
|
|
#define KEYRING_BAM_BITS (KEYRING_BAM_BYTES<<3)
|
|
|
|
#define KEYRING_SLAB_SIZE (KEYRING_PAGE_SIZE*KEYRING_BAM_BITS)
|
|
|
|
typedef struct keyring_bam {
|
|
|
|
off_t file_offset;
|
|
|
|
unsigned char bitmap[KEYRING_BAM_BYTES];
|
|
|
|
struct keyring_bam *next;
|
|
|
|
} keyring_bam;
|
|
|
|
|
|
|
|
#define KEYRING_MAX_CONTEXTS 256
|
|
|
|
typedef struct keyring_file {
|
|
|
|
int context_count;
|
|
|
|
keyring_bam *bam;
|
|
|
|
keyring_context *contexts[KEYRING_MAX_CONTEXTS];
|
|
|
|
FILE *file;
|
|
|
|
off_t file_size;
|
|
|
|
} keyring_file;
|
|
|
|
|
|
|
|
void keyring_free(keyring_file *k);
|
|
|
|
void keyring_free_context(keyring_context *c);
|
|
|
|
void keyring_free_identity(keyring_identity *id);
|
|
|
|
void keyring_free_keypair(keypair *kp);
|
|
|
|
int keyring_identity_mac(keyring_context *c,keyring_identity *id,
|
|
|
|
unsigned char *pkrsalt,unsigned char *mac);
|
|
|
|
#define KEYTYPE_CRYPTOBOX 0x01
|
|
|
|
#define KEYTYPE_CRYPTOSIGN 0x02
|
|
|
|
#define KEYTYPE_RHIZOME 0x03
|
|
|
|
/* DIDs aren't really keys, but the keyring is a real handy place to keep them,
|
|
|
|
and keep them private if people so desire */
|
|
|
|
#define KEYTYPE_DID 0x04
|
|
|
|
|
|
|
|
/* handle to keyring file for use in running instance */
|
|
|
|
extern keyring_file *keyring;
|
|
|
|
|
|
|
|
/* Public calls to keyring management */
|
|
|
|
keyring_file *keyring_open(char *file);
|
2012-04-23 07:42:10 +00:00
|
|
|
keyring_file *keyring_open_with_pins(const char *pinlist);
|
|
|
|
int keyring_enter_pin(keyring_file *k, const char *pin);
|
|
|
|
int keyring_enter_pins(keyring_file *k, const char *pinlist);
|
2012-05-01 05:08:09 +00:00
|
|
|
int keyring_set_did(keyring_identity *id,char *did,char *name);
|
2012-06-08 08:55:43 +00:00
|
|
|
int keyring_sanitise_position(const keyring_file *k,int *cn,int *in,int *kp);
|
|
|
|
int keyring_next_keytype(const keyring_file *k, int *cn, int *in, int *kp, int keytype);
|
|
|
|
int keyring_next_identity(const keyring_file *k,int *cn,int *in,int *kp);
|
|
|
|
int keyring_identity_find_keytype(const keyring_file *k, int cn, int in, int keytype);
|
|
|
|
int keyring_find_did(const keyring_file *k,int *cn,int *in,int *kp,char *did);
|
|
|
|
int keyring_find_sid(const keyring_file *k,int *cn,int *in,int *kp, const unsigned char *sid);
|
2012-04-15 20:36:43 +00:00
|
|
|
unsigned char *keyring_find_sas_private(keyring_file *k,unsigned char *sid,
|
|
|
|
unsigned char **sas_public);
|
2012-04-14 17:47:36 +00:00
|
|
|
unsigned char *keyring_find_sas_public(keyring_file *k,unsigned char *sid);
|
|
|
|
|
2012-04-12 23:55:03 +00:00
|
|
|
int keyring_commit(keyring_file *k);
|
2012-07-06 03:47:53 +00:00
|
|
|
keyring_identity *keyring_create_identity(keyring_file *k,keyring_context *c, const char *pin);
|
2012-04-12 23:55:03 +00:00
|
|
|
int keyring_seed(keyring_file *k);
|
2012-07-06 03:47:53 +00:00
|
|
|
void keyring_identity_extract(const keyring_identity *id, const unsigned char **sidp, const char **didp, const char **namep);
|
2010-07-13 12:15:46 +00:00
|
|
|
|
|
|
|
/* Make sure we have space to put bytes of the packet as we go along */
|
2012-05-24 07:41:55 +00:00
|
|
|
#define CHECK_PACKET_LEN(B) {if (((*packet_len)+(B))>=packet_maxlen) { return WHY("Packet composition ran out of space."); } }
|
2010-07-13 12:15:46 +00:00
|
|
|
|
|
|
|
extern int sock;
|
|
|
|
|
2011-09-12 20:07:24 +00:00
|
|
|
typedef struct overlay_address_table {
|
|
|
|
unsigned char epoch;
|
|
|
|
char sids[256][SID_SIZE];
|
|
|
|
/* 0x00 = not set, which thus limits us to using only 255 (0x01-0xff) of the indexes for
|
2012-07-02 03:49:54 +00:00
|
|
|
storing addresses.
|
|
|
|
By spending an extra 256 bytes we reduce, but not eliminate the problem of collisions.
|
|
|
|
Will think about a complete solution later.
|
|
|
|
*/
|
2011-09-12 20:07:24 +00:00
|
|
|
unsigned char byfirstbyte[256][2];
|
|
|
|
/* next free entry in sid[] */
|
|
|
|
unsigned char next_free;
|
|
|
|
} overlay_address_table;
|
|
|
|
|
|
|
|
typedef struct sid {
|
|
|
|
unsigned char b[SID_SIZE];
|
|
|
|
} sid;
|
|
|
|
|
|
|
|
typedef struct overlay_address_cache {
|
|
|
|
int size;
|
|
|
|
int shift; /* Used to calculat lookup function, which is (b[0].b[1].b[2]>>shift) */
|
|
|
|
sid *sids; /* one entry per bucket, to keep things simple. */
|
|
|
|
/* XXX Should have a means of changing the hash function so that naughty people can't try
|
2012-07-02 03:49:54 +00:00
|
|
|
to force our cache to flush with duplicate addresses?
|
|
|
|
But we must use only the first 24 bits of the address due to abbreviation policies,
|
|
|
|
so our options are limited.
|
|
|
|
For now the hash will be the first k bits.
|
|
|
|
*/
|
2011-09-12 20:07:24 +00:00
|
|
|
} overlay_address_cache;
|
|
|
|
|
|
|
|
extern sid overlay_abbreviate_current_sender;
|
2011-08-12 19:05:11 +00:00
|
|
|
|
2011-08-17 01:22:17 +00:00
|
|
|
typedef struct overlay_frame {
|
|
|
|
struct overlay_frame *prev;
|
|
|
|
struct overlay_frame *next;
|
2012-07-02 03:49:54 +00:00
|
|
|
|
2011-08-17 01:22:17 +00:00
|
|
|
unsigned int type;
|
|
|
|
unsigned int modifiers;
|
2012-07-02 03:49:54 +00:00
|
|
|
|
2011-08-17 01:22:17 +00:00
|
|
|
unsigned char ttl;
|
2012-07-02 03:49:54 +00:00
|
|
|
|
2012-04-13 18:36:08 +00:00
|
|
|
/* Mark which interfaces the frame has been sent on,
|
2012-07-02 03:49:54 +00:00
|
|
|
so that we can ensure that broadcast frames get sent
|
|
|
|
exactly once on each interface */
|
2012-04-13 18:36:08 +00:00
|
|
|
int isBroadcast;
|
|
|
|
unsigned char broadcast_sent_via[OVERLAY_MAX_INTERFACES];
|
2012-07-02 03:49:54 +00:00
|
|
|
|
2011-08-17 01:22:17 +00:00
|
|
|
unsigned char nexthop[32];
|
|
|
|
int nexthop_address_status;
|
2011-09-05 04:00:17 +00:00
|
|
|
int nexthop_interface; /* which interface the next hop should be attempted on */
|
2012-07-02 03:49:54 +00:00
|
|
|
|
2011-08-17 01:22:17 +00:00
|
|
|
unsigned char destination[32];
|
|
|
|
unsigned char source[32];
|
2012-07-02 03:49:54 +00:00
|
|
|
|
2012-01-12 06:17:24 +00:00
|
|
|
/* IPv4 node frame was received from (if applicable) */
|
|
|
|
struct sockaddr *recvaddr;
|
2012-07-02 03:49:54 +00:00
|
|
|
|
2011-08-17 01:22:17 +00:00
|
|
|
/* Actual payload */
|
2012-07-17 06:00:50 +00:00
|
|
|
// TODO refactor *all* packet parsing so that the payload is not copied or allocated unless it must be forwarded.
|
2011-09-05 02:49:53 +00:00
|
|
|
struct overlay_buffer *payload;
|
2012-07-02 03:49:54 +00:00
|
|
|
|
2011-08-17 01:22:17 +00:00
|
|
|
int rfs; /* remainder of frame size */
|
2011-09-05 07:00:50 +00:00
|
|
|
|
2011-08-17 01:22:17 +00:00
|
|
|
long long enqueued_at;
|
2012-07-02 03:49:54 +00:00
|
|
|
|
2011-08-17 01:22:17 +00:00
|
|
|
} overlay_frame;
|
|
|
|
|
2011-05-16 07:28:25 +00:00
|
|
|
|
2012-07-02 06:34:00 +00:00
|
|
|
struct profile_total {
|
|
|
|
struct profile_total *_next;
|
2012-07-02 03:49:54 +00:00
|
|
|
int _initialised;
|
|
|
|
const char *name;
|
|
|
|
long long max_time;
|
|
|
|
long long total_time;
|
2012-07-12 00:45:16 +00:00
|
|
|
long long child_time;
|
2012-07-02 03:49:54 +00:00
|
|
|
int calls;
|
|
|
|
};
|
|
|
|
|
2012-07-12 00:45:16 +00:00
|
|
|
struct call_stats{
|
|
|
|
long long enter_time;
|
|
|
|
long long child_time;
|
|
|
|
struct profile_total *totals;
|
|
|
|
struct call_stats *prev;
|
|
|
|
};
|
|
|
|
|
2012-07-02 03:49:54 +00:00
|
|
|
struct sched_ent;
|
|
|
|
|
|
|
|
typedef void (*ALARM_FUNCP) (struct sched_ent *alarm);
|
|
|
|
|
|
|
|
struct sched_ent{
|
|
|
|
struct sched_ent *_next;
|
|
|
|
struct sched_ent *_prev;
|
|
|
|
|
|
|
|
ALARM_FUNCP function;
|
|
|
|
void *context;
|
|
|
|
struct pollfd poll;
|
2012-07-12 00:45:16 +00:00
|
|
|
// when we should first consider the alarm
|
2012-07-02 03:49:54 +00:00
|
|
|
long long alarm;
|
2012-07-12 00:45:16 +00:00
|
|
|
// the order we will prioritise the alarm
|
|
|
|
long long deadline;
|
2012-07-02 06:34:00 +00:00
|
|
|
struct profile_total *stats;
|
2012-07-02 03:49:54 +00:00
|
|
|
int _poll_index;
|
|
|
|
};
|
|
|
|
|
2012-07-25 08:34:16 +00:00
|
|
|
#define STRUCT_SCHED_ENT_UNUSED ((struct sched_ent){NULL, NULL, NULL, NULL, {-1, 0, 0}, 0LL, 0LL, NULL, -1})
|
2012-07-02 03:49:54 +00:00
|
|
|
|
2011-08-08 14:41:46 +00:00
|
|
|
extern int overlayMode;
|
2012-04-13 18:36:08 +00:00
|
|
|
|
2012-07-25 07:23:44 +00:00
|
|
|
#define INTERFACE_STATE_FREE 0
|
|
|
|
#define INTERFACE_STATE_UP 1
|
|
|
|
#define INTERFACE_STATE_DOWN 2
|
|
|
|
#define INTERFACE_STATE_DETECTING 3
|
|
|
|
|
2011-08-08 06:41:05 +00:00
|
|
|
typedef struct overlay_interface {
|
2012-07-02 03:49:54 +00:00
|
|
|
struct sched_ent alarm;
|
2011-08-12 07:47:29 +00:00
|
|
|
char name[80];
|
2011-08-14 08:36:39 +00:00
|
|
|
int offset;
|
|
|
|
int fileP;
|
2011-08-08 06:41:05 +00:00
|
|
|
int bits_per_second;
|
|
|
|
int port;
|
|
|
|
int type;
|
|
|
|
/* Number of milli-seconds per tick for this interface, which is basically related to the
|
2012-07-02 03:49:54 +00:00
|
|
|
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.
|
|
|
|
*/
|
2011-08-20 09:36:15 +00:00
|
|
|
int tick_ms; /* milliseconds per tick */
|
2012-07-02 03:49:54 +00:00
|
|
|
|
2011-08-08 14:41:46 +00:00
|
|
|
/* The time of the last tick on this interface in milli seconds */
|
|
|
|
long long last_tick_ms;
|
2011-08-15 07:27:29 +00:00
|
|
|
/* How many times have we abbreviated our address since we last announced it in full? */
|
|
|
|
int ticks_since_sent_full_address;
|
2012-07-02 03:49:54 +00:00
|
|
|
|
2012-05-14 06:14:36 +00:00
|
|
|
/* sequence number of last packet sent on this interface.
|
2012-07-02 03:49:54 +00:00
|
|
|
Used to allow NACKs that can request retransmission of recent packets.
|
|
|
|
*/
|
2011-08-12 06:34:56 +00:00
|
|
|
int sequence_number;
|
2012-05-14 06:14:36 +00:00
|
|
|
/* XXX need recent packet buffers to support the above */
|
2012-07-02 03:49:54 +00:00
|
|
|
|
2012-07-25 07:23:44 +00:00
|
|
|
/* We need to make sure that interface name and broadcast address is unique for all interfaces that are UP.
|
|
|
|
We bind a separate socket per interface / broadcast address Broadcast address and netmask, if known
|
2012-07-02 03:49:54 +00:00
|
|
|
We really only case about distinct broadcast addresses on interfaces.
|
|
|
|
Also simplifies aliases on interfaces. */
|
2012-07-25 07:23:44 +00:00
|
|
|
struct sockaddr_in address;
|
2011-08-08 14:41:46 +00:00
|
|
|
struct sockaddr_in broadcast_address;
|
2012-07-02 03:49:54 +00:00
|
|
|
|
2011-08-08 14:41:46 +00:00
|
|
|
/* Not necessarily the real MTU, but the largest frame size we are willing to TX on this interface.
|
2012-07-02 03:49:54 +00:00
|
|
|
For radio links the actual maximum and the maximum that is likely to be delivered reliably are
|
|
|
|
potentially two quite different values. */
|
2011-08-08 14:41:46 +00:00
|
|
|
int mtu;
|
2012-07-02 03:49:54 +00:00
|
|
|
|
2012-07-25 07:23:44 +00:00
|
|
|
/* 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;
|
2011-08-08 06:41:05 +00:00
|
|
|
} overlay_interface;
|
|
|
|
|
|
|
|
/* Maximum interface count is rather arbitrary.
|
2012-07-02 03:49:54 +00:00
|
|
|
Memory consumption is O(n) with respect to this parameter, so let's not make it too big for now.
|
|
|
|
*/
|
2011-08-08 06:41:05 +00:00
|
|
|
extern overlay_interface overlay_interfaces[OVERLAY_MAX_INTERFACES];
|
2012-01-08 17:49:52 +00:00
|
|
|
extern int overlay_last_interface_number; // used to remember where a packet came from
|
2011-08-20 09:36:15 +00:00
|
|
|
extern unsigned int overlay_sequence_number;
|
2011-08-08 06:41:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
typedef struct overlay_peer {
|
|
|
|
unsigned char address[SIDDIDFIELD_LEN];
|
2012-07-02 03:49:54 +00:00
|
|
|
|
2011-08-08 06:41:05 +00:00
|
|
|
/* Scores and score update times for reaching this node via various interfaces */
|
|
|
|
int known_routes[OVERLAY_MAX_INTERFACES];
|
|
|
|
unsigned short scores[OVERLAY_MAX_INTERFACES][OVERLAY_MAX_PEERS];
|
2012-07-02 03:49:54 +00:00
|
|
|
|
2011-08-08 06:41:05 +00:00
|
|
|
/* last_regeneration is the time that this peer was created/replaced with another peer.
|
2012-07-02 03:49:54 +00:00
|
|
|
lastupdate[] indicates the time that another peer's reachability report
|
|
|
|
caused us to update our score to reach via that peer.
|
|
|
|
If lastupdate[x][y] is older than last_regeneration[y], then we must
|
|
|
|
ignore the entry, because the lastupdate[x][y] entry references a previous
|
|
|
|
generation of that peer, i.e., not to the peer we think it does.
|
|
|
|
|
|
|
|
This slight convolution allows us to replace peers without having to touch the
|
|
|
|
records of every other peer in our list.
|
|
|
|
*/
|
2011-08-08 06:41:05 +00:00
|
|
|
int last_regeneration;
|
|
|
|
unsigned int lastupdate[OVERLAY_MAX_INTERFACES][OVERLAY_MAX_PEERS];
|
|
|
|
} overlay_peer;
|
|
|
|
|
|
|
|
extern overlay_peer overlay_peers[OVERLAY_MAX_PEERS];
|
|
|
|
|
|
|
|
typedef struct overlay_buffer {
|
|
|
|
unsigned char *bytes;
|
2012-07-18 05:00:16 +00:00
|
|
|
// position of data read / written
|
2011-08-08 06:41:05 +00:00
|
|
|
int length;
|
2012-07-18 05:00:16 +00:00
|
|
|
// allocated size of buffer
|
2011-08-08 06:41:05 +00:00
|
|
|
int allocSize;
|
2012-07-18 05:00:16 +00:00
|
|
|
// remembered position for rewinding
|
2011-08-08 06:41:05 +00:00
|
|
|
int checkpointLength;
|
2012-07-18 05:00:16 +00:00
|
|
|
// maximum allowed bytes for reading / writing
|
2011-08-08 06:41:05 +00:00
|
|
|
int sizeLimit;
|
2011-08-17 01:22:17 +00:00
|
|
|
int var_length_offset;
|
|
|
|
int var_length_bytes;
|
2011-08-08 06:41:05 +00:00
|
|
|
} overlay_buffer;
|
|
|
|
|
|
|
|
int ob_unlimitsize(overlay_buffer *b);
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct overlay_txqueue {
|
2011-08-17 01:22:17 +00:00
|
|
|
struct overlay_frame *first;
|
|
|
|
struct overlay_frame *last;
|
2011-09-05 03:19:37 +00:00
|
|
|
int length; /* # frames in queue */
|
|
|
|
int maxLength; /* max # frames in queue before we consider ourselves congested */
|
2012-07-02 03:49:54 +00:00
|
|
|
|
2012-07-12 01:11:47 +00:00
|
|
|
/* wait until first->enqueued_at+transmit_delay before trying to force the transmission of a packet */
|
|
|
|
int transmit_delay;
|
|
|
|
|
|
|
|
/* if servald is busy, wait this long before trying to force the transmission of a packet */
|
|
|
|
int grace_period;
|
|
|
|
|
2011-08-08 06:41:05 +00:00
|
|
|
/* Latency target in ms for this traffic class.
|
2012-07-02 03:49:54 +00:00
|
|
|
Frames older than the latency target will get dropped. */
|
2011-08-08 06:41:05 +00:00
|
|
|
int latencyTarget;
|
|
|
|
|
|
|
|
/* XXX Need to initialise these:
|
2012-07-02 03:49:54 +00:00
|
|
|
Real-time queue for voice (<200ms ?)
|
|
|
|
Real-time queue for video (<200ms ?) (lower priority than voice)
|
|
|
|
Ordinary service queue (<3 sec ?)
|
|
|
|
Rhizome opportunistic queue (infinity)
|
|
|
|
|
|
|
|
(Mesh management doesn't need a queue, as each overlay packet is tagged with some mesh management information)
|
|
|
|
*/
|
2011-08-08 06:41:05 +00:00
|
|
|
} overlay_txqueue;
|
|
|
|
|
2011-09-05 03:04:54 +00:00
|
|
|
|
|
|
|
extern overlay_txqueue overlay_tx[OQ_MAX];
|
2011-08-08 06:41:05 +00:00
|
|
|
|
2012-07-03 06:06:51 +00:00
|
|
|
ssize_t recvwithttl(int sock, unsigned char *buffer, size_t bufferlen, int *ttl, struct sockaddr *recvaddr, socklen_t *recvaddrlen);
|
2012-07-02 03:49:54 +00:00
|
|
|
|
|
|
|
int is_xsubstring(const char *text, int len);
|
|
|
|
int is_xstring(const char *text, int len);
|
|
|
|
char *tohex(char *dstHex, const unsigned char *srcBinary, size_t bytes);
|
|
|
|
size_t fromhex(unsigned char *dstBinary, const char *srcHex, size_t bytes);
|
|
|
|
int fromhexstr(unsigned char *dstBinary, const char *srcHex, size_t bytes);
|
|
|
|
int hexvalue(char c);
|
|
|
|
char *str_toupper_inplace(char *s);
|
|
|
|
|
2012-07-12 06:44:25 +00:00
|
|
|
int str_is_subscriber_id(const char *sid);
|
|
|
|
int strn_is_subscriber_id(const char *sid, size_t *lenp);
|
2012-07-23 02:53:17 +00:00
|
|
|
int str_is_did(const char *did);
|
|
|
|
int strn_is_did(const char *did, size_t *lenp);
|
2012-07-23 08:59:57 +00:00
|
|
|
int str_is_uri(const char *uri);
|
2012-07-12 06:44:25 +00:00
|
|
|
|
2012-07-02 03:49:54 +00:00
|
|
|
int stowSid(unsigned char *packet, int ofs, const char *sid);
|
|
|
|
int stowDid(unsigned char *packet,int *ofs,char *did);
|
|
|
|
int isFieldZeroP(unsigned char *packet,int start,int count);
|
|
|
|
void srandomdev();
|
|
|
|
int respondSimple(keyring_identity *id,
|
|
|
|
int action,unsigned char *action_text,int action_len,
|
|
|
|
unsigned char *transaction_id,int recvttl,
|
|
|
|
struct sockaddr *recvaddr,int cryptoFlags);
|
|
|
|
long long gettime_ms();
|
|
|
|
int server_pid();
|
|
|
|
void server_save_argv(int argc, const char *const *argv);
|
|
|
|
int server(char *backing_file);
|
|
|
|
int server_create_stopfile();
|
|
|
|
int server_remove_stopfile();
|
|
|
|
int server_check_stopfile();
|
|
|
|
void serverCleanUp();
|
|
|
|
int isTransactionInCache(unsigned char *transaction_id);
|
|
|
|
void insertTransactionInCache(unsigned char *transaction_id);
|
|
|
|
|
2012-07-03 06:06:51 +00:00
|
|
|
int packetOk(struct overlay_interface *interface,unsigned char *packet, size_t len,
|
2012-07-02 03:49:54 +00:00
|
|
|
unsigned char *transaction_id, int recvttl,
|
2012-07-03 06:06:51 +00:00
|
|
|
struct sockaddr *recvaddr, size_t recvaddrlen,int parseP);
|
|
|
|
int process_packet(unsigned char *packet, size_t len, int recvttl,struct sockaddr *sender, size_t sender_len);
|
2012-07-02 03:49:54 +00:00
|
|
|
int packetMakeHeader(unsigned char *packet,int packet_maxlen,int *packet_len,unsigned char *transaction_id,int cryptoflags);
|
|
|
|
int packetSetDid(unsigned char *packet,int packet_maxlen,int *packet_len,char *did);
|
|
|
|
int packetSetSidFromId(unsigned char *packet,int packet_maxlen,int *packet_len,
|
|
|
|
keyring_identity *id);
|
|
|
|
int packetFinalise(unsigned char *packet,int packet_maxlen,int recvttl,
|
|
|
|
int *packet_len,int cryptoflags);
|
|
|
|
int extractResponses(struct in_addr sender,unsigned char *buffer,int len,struct response_set *responses);
|
|
|
|
int packetGetID(unsigned char *packet,int len,char *did,char *sid);
|
|
|
|
int getPeerList();
|
|
|
|
int sendToPeers(unsigned char *packet,int packet_len,int method,int peerId,struct response_set *responses);
|
|
|
|
int getReplyPackets(int method,int peer,int batchP,struct response_set *responses,
|
|
|
|
unsigned char *transaction_id,struct sockaddr *recvaddr,int timeout);
|
|
|
|
int clearResponse(struct response **response);
|
|
|
|
int packageVariableSegment(unsigned char *data,int *dlen,
|
|
|
|
struct response *h,
|
|
|
|
int offset,int buffer_size);
|
|
|
|
int packetDecipher(unsigned char *packet,int len,int cipher);
|
|
|
|
int safeZeroField(unsigned char *packet,int start,int count);
|
|
|
|
int unpackageVariableSegment(unsigned char *data,int dlen,int flags,struct response *r);
|
2012-07-03 08:29:30 +00:00
|
|
|
int extractSid(const unsigned char *packet,int *ofs, char *sid);
|
2012-07-02 03:49:54 +00:00
|
|
|
int hlrSetVariable(unsigned char *hlr,int hofs,int varid,int varinstance,
|
|
|
|
unsigned char *value,int len);
|
|
|
|
int extractDid(unsigned char *packet,int *ofs,char *did);
|
|
|
|
char *hlrSid(unsigned char *hlr, int ofs, char *sid);
|
|
|
|
int processRequest(unsigned char *packet,int len,struct sockaddr *sender,int sender_len,
|
|
|
|
unsigned char *transaction_id,int recvttl,char *did,char *sid);
|
|
|
|
|
|
|
|
int extractRequest(unsigned char *packet,int *packet_ofs,int packet_len,
|
|
|
|
int *itemId,int *instance,unsigned char *value,
|
|
|
|
int *start_offset,int *max_offset,int *flags);
|
|
|
|
int hlrGetVariable(unsigned char *hlr,int hofs,int varid,int varinstance,
|
|
|
|
unsigned char *value,int *len);
|
|
|
|
int dumpResponses(struct response_set *responses);
|
|
|
|
int eraseLastResponse(struct response_set *responses);
|
2012-07-03 06:06:51 +00:00
|
|
|
int dropPacketP(size_t packet_len);
|
2012-07-02 03:49:54 +00:00
|
|
|
int clearResponses(struct response_set *responses);
|
|
|
|
int responseFromPeerP(struct response_set *responses,int peerId);
|
|
|
|
int responseFromPeer(struct response_set *responses,int peerId);
|
|
|
|
int additionalPeer(char *peer);
|
|
|
|
int readRoutingTable(struct in_addr peers[],int *peer_count,int peer_max);
|
|
|
|
int readBatmanPeerFile(char *file_path,struct in_addr peers[],int *peer_count,int peer_max);
|
|
|
|
int getBatmanPeerList(char *socket_path,struct in_addr peers[],int *peer_count,int peer_max);
|
|
|
|
int hlrDump(unsigned char *hlr,int hofs);
|
|
|
|
int fixResponses(struct response_set *responses);
|
|
|
|
int importHlr(char *textfile);
|
|
|
|
int exportHlr(unsigned char *hlr,char *text);
|
|
|
|
int openHlrFile(char *backing_file,int size);
|
|
|
|
int asteriskObtainGateway(char *requestor_sid,char *did,char *uri_out);
|
|
|
|
int packetOkDNA(unsigned char *packet,int len,unsigned char *transaction_id,
|
2012-07-03 06:06:51 +00:00
|
|
|
int recvttl,struct sockaddr *recvaddr, size_t recvaddrlen,int parseP);
|
|
|
|
int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, size_t len,
|
2012-07-02 03:49:54 +00:00
|
|
|
unsigned char *transaction_id,int recvttl,
|
2012-07-03 06:06:51 +00:00
|
|
|
struct sockaddr *recvaddr, size_t recvaddrlen,int parseP);
|
2012-07-02 03:49:54 +00:00
|
|
|
int prepareGateway(char *gatewayspec);
|
|
|
|
int packetSendRequest(int method,unsigned char *packet,int packet_len,int batchP,
|
|
|
|
unsigned char *transaction_id,struct sockaddr *recvaddr,
|
|
|
|
struct response_set *responses);
|
|
|
|
int readArpTable(struct in_addr peers[],int *peer_count,int peer_max);
|
|
|
|
|
|
|
|
int overlay_frame_process(struct overlay_interface *interface,overlay_frame *f);
|
|
|
|
int overlay_frame_resolve_addresses(overlay_frame *f);
|
|
|
|
|
2012-07-19 08:29:45 +00:00
|
|
|
#define alloca_toprint(dstlen,buf,len) toprint((char *)alloca(toprint_strlen((dstlen), (buf), (len)) + 1), (dstlen), (buf), (len))
|
2012-07-11 04:47:53 +00:00
|
|
|
|
|
|
|
#define alloca_tohex(buf,len) tohex((char *)alloca((len)*2+1), (buf), (len))
|
|
|
|
#define alloca_tohex_sid(sid) alloca_tohex((sid), SID_SIZE)
|
2012-06-08 05:57:15 +00:00
|
|
|
|
2011-08-08 06:41:05 +00:00
|
|
|
overlay_buffer *ob_new(int size);
|
2012-07-18 05:00:16 +00:00
|
|
|
overlay_buffer *ob_static(unsigned char *bytes, int size);
|
2011-08-08 06:41:05 +00:00
|
|
|
int ob_free(overlay_buffer *b);
|
|
|
|
int ob_checkpoint(overlay_buffer *b);
|
|
|
|
int ob_rewind(overlay_buffer *b);
|
2012-07-18 05:00:16 +00:00
|
|
|
int ob_setlength(overlay_buffer *b,int bytes);
|
2011-08-08 06:41:05 +00:00
|
|
|
int ob_limitsize(overlay_buffer *b,int bytes);
|
|
|
|
int ob_unlimitsize(overlay_buffer *b);
|
|
|
|
int ob_makespace(overlay_buffer *b,int bytes);
|
2011-09-03 21:06:39 +00:00
|
|
|
int ob_append_byte(overlay_buffer *b,unsigned char byte);
|
2011-08-08 06:41:05 +00:00
|
|
|
int ob_append_bytes(overlay_buffer *b,unsigned char *bytes,int count);
|
2012-04-13 16:44:41 +00:00
|
|
|
unsigned char *ob_append_space(overlay_buffer *b,int count);
|
2011-08-08 06:41:05 +00:00
|
|
|
int ob_append_short(overlay_buffer *b,unsigned short v);
|
|
|
|
int ob_append_int(overlay_buffer *b,unsigned int v);
|
2011-08-17 01:22:17 +00:00
|
|
|
int ob_patch_rfs(overlay_buffer *b,int l);
|
|
|
|
int ob_indel_space(overlay_buffer *b,int offset,int shift);
|
|
|
|
int ob_append_rfs(overlay_buffer *b,int l);
|
2012-07-18 05:00:16 +00:00
|
|
|
int ob_setbyte(overlay_buffer *b,int ofs,unsigned char value);
|
|
|
|
int ob_getbyte(overlay_buffer *b,int ofs);
|
|
|
|
int ob_dump(overlay_buffer *b,char *desc);
|
|
|
|
unsigned int ob_get_int(overlay_buffer *b,int offset);
|
2011-08-08 06:41:05 +00:00
|
|
|
|
2011-08-17 01:22:17 +00:00
|
|
|
int op_free(overlay_frame *p);
|
2012-04-14 01:26:03 +00:00
|
|
|
overlay_frame *op_dup(overlay_frame *f);
|
2011-08-08 14:41:46 +00:00
|
|
|
|
2011-08-08 06:41:05 +00:00
|
|
|
long long parse_quantity(char *q);
|
|
|
|
|
2012-07-25 05:23:53 +00:00
|
|
|
int overlay_interface_init(char *name,struct sockaddr_in *src_addr,struct sockaddr_in *broadcast,
|
2012-04-28 02:55:19 +00:00
|
|
|
int speed_in_bits,int port,int type);
|
2012-07-25 07:23:44 +00:00
|
|
|
int overlay_interface_init_socket(int i);
|
2011-08-08 14:41:46 +00:00
|
|
|
long long overlay_time_until_next_tick();
|
|
|
|
int overlay_rx_messages();
|
2012-07-02 03:49:54 +00:00
|
|
|
|
2011-08-08 14:41:46 +00:00
|
|
|
int overlay_add_selfannouncement();
|
2011-08-17 01:22:17 +00:00
|
|
|
int overlay_frame_package_fmt1(overlay_frame *p,overlay_buffer *b);
|
2012-05-07 04:19:38 +00:00
|
|
|
int overlay_interface_args(const char *arg);
|
2012-07-12 01:06:41 +00:00
|
|
|
int overlay_get_nexthop(unsigned char *d,unsigned char *nexthop,int *interface);
|
2012-01-08 17:49:52 +00:00
|
|
|
int overlay_sendto(struct sockaddr_in *recipientaddr,unsigned char *bytes,int len);
|
2012-01-08 18:27:13 +00:00
|
|
|
int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e);
|
2012-01-08 23:25:21 +00:00
|
|
|
int overlay_add_local_identity(unsigned char *s);
|
|
|
|
int overlay_address_is_local(unsigned char *s);
|
2012-07-12 01:11:47 +00:00
|
|
|
void overlay_update_queue_schedule(overlay_txqueue *queue, overlay_frame *frame);
|
|
|
|
void overlay_send_packet(struct sched_ent *alarm);
|
2012-07-17 06:29:06 +00:00
|
|
|
int overlay_resolve_next_hop(overlay_frame *frame);
|
2011-08-08 14:41:46 +00:00
|
|
|
|
|
|
|
extern int overlay_interface_count;
|
2011-08-12 06:15:26 +00:00
|
|
|
|
2012-01-08 23:25:21 +00:00
|
|
|
extern int overlay_local_identity_count;
|
|
|
|
extern unsigned char *overlay_local_identities[OVERLAY_MAX_LOCAL_IDENTITIES];
|
|
|
|
|
2011-09-03 21:18:41 +00:00
|
|
|
int overlay_abbreviate_address(unsigned char *in,unsigned char *out,int *ofs);
|
2011-08-17 01:22:17 +00:00
|
|
|
int overlay_abbreviate_append_address(overlay_buffer *b,unsigned char *a);
|
|
|
|
|
2012-07-02 03:49:54 +00:00
|
|
|
int overlay_abbreviate_expand_address(unsigned char *in,int *inofs,unsigned char *out,int *ofs);
|
2011-08-15 14:22:29 +00:00
|
|
|
int overlay_abbreviate_cache_address(unsigned char *sid);
|
2011-08-14 18:44:11 +00:00
|
|
|
int overlay_abbreviate_cache_lookup(unsigned char *in,unsigned char *out,int *ofs,
|
|
|
|
int prefix_bytes,int index_bytes);
|
|
|
|
int overlay_abbreviate_remember_index(int index_byte_count,unsigned char *in,unsigned char *index_bytes);
|
2011-08-15 10:51:00 +00:00
|
|
|
extern int overlay_abbreviate_repeat_policy;
|
2011-08-15 11:50:30 +00:00
|
|
|
int overlay_abbreviate_set_most_recent_address(unsigned char *in);
|
2012-05-06 23:01:53 +00:00
|
|
|
int overlay_abbreviate_clear_most_recent_address();
|
2011-08-14 18:44:11 +00:00
|
|
|
|
2011-08-17 01:22:17 +00:00
|
|
|
int rfs_length(int l);
|
|
|
|
int rfs_encode(int l,unsigned char *b);
|
|
|
|
int rfs_decode(unsigned char *b,int *offset);
|
2011-08-15 07:27:29 +00:00
|
|
|
|
2011-09-01 13:14:30 +00:00
|
|
|
typedef struct overlay_neighbour_observation {
|
2011-08-29 06:50:27 +00:00
|
|
|
/* Sequence numbers are handled as ranges because the tick
|
|
|
|
rate can vary between interfaces, and we want to be able to
|
|
|
|
estimate the reliability of links to nodes that may have
|
|
|
|
several available interfaces.
|
|
|
|
We don't want sequence numbers to wrap too often, but we
|
|
|
|
would also like to support fairly fast ticking interfaces,
|
|
|
|
e.g., for gigabit type links. So lets go with 1ms granularity. */
|
2011-09-01 13:14:30 +00:00
|
|
|
unsigned int s1;
|
|
|
|
unsigned int s2;
|
|
|
|
long long time_ms;
|
2011-09-01 13:52:08 +00:00
|
|
|
unsigned char sender_interface;
|
|
|
|
unsigned char valid;
|
2011-09-01 13:14:30 +00:00
|
|
|
} overlay_neighbour_observation;
|
|
|
|
|
|
|
|
typedef struct overlay_node_observation {
|
2011-09-12 17:15:12 +00:00
|
|
|
unsigned char observed_score; /* serves as validty check also */
|
|
|
|
unsigned char corrected_score;
|
2011-09-11 10:39:47 +00:00
|
|
|
unsigned char gateways_en_route;
|
2011-09-12 17:24:03 +00:00
|
|
|
unsigned char RESERVED; /* for alignment */
|
2012-04-29 02:26:47 +00:00
|
|
|
unsigned char interface;
|
2011-08-29 06:50:27 +00:00
|
|
|
long long rx_time;
|
|
|
|
unsigned char sender_prefix[OVERLAY_SENDER_PREFIX_LENGTH];
|
|
|
|
} overlay_node_observation;
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct overlay_node {
|
|
|
|
unsigned char sid[SID_SIZE];
|
|
|
|
int neighbour_id; /* 0=not a neighbour */
|
|
|
|
int most_recent_observation_id;
|
2011-09-12 17:49:54 +00:00
|
|
|
int best_link_score;
|
|
|
|
int best_observation;
|
2012-04-29 02:26:47 +00:00
|
|
|
unsigned int last_first_hand_observation_time_millisec;
|
2011-09-12 17:49:54 +00:00
|
|
|
long long last_observation_time_ms;
|
|
|
|
/* When did we last advertise this node on each interface, and what score
|
|
|
|
did we advertise? */
|
|
|
|
long long most_recent_advertisment[OVERLAY_MAX_INTERFACES];
|
|
|
|
unsigned char most_recent_advertised_score[OVERLAY_MAX_INTERFACES];
|
2011-08-29 06:50:27 +00:00
|
|
|
overlay_node_observation observations[OVERLAY_MAX_OBSERVATIONS];
|
|
|
|
} overlay_node;
|
|
|
|
|
2011-09-01 13:14:30 +00:00
|
|
|
typedef struct overlay_neighbour {
|
2011-09-01 13:52:08 +00:00
|
|
|
long long last_observation_time_ms;
|
2012-04-22 10:46:48 +00:00
|
|
|
long long last_metric_update;
|
2011-09-01 13:52:08 +00:00
|
|
|
int most_recent_observation_id;
|
2011-09-01 13:14:30 +00:00
|
|
|
overlay_neighbour_observation observations[OVERLAY_MAX_OBSERVATIONS];
|
2011-09-01 13:52:08 +00:00
|
|
|
overlay_node *node;
|
2011-09-04 07:08:54 +00:00
|
|
|
|
|
|
|
/* Scores of visibility from each of the neighbours interfaces.
|
|
|
|
This is so that the sender knows which interface to use to reach us.
|
|
|
|
*/
|
|
|
|
unsigned char scores[OVERLAY_MAX_INTERFACES];
|
2011-09-05 07:00:50 +00:00
|
|
|
|
|
|
|
/* One-byte index entries for address abbreviation */
|
|
|
|
unsigned char one_byte_index_address_prefixes[256][OVERLAY_SENDER_PREFIX_LENGTH];
|
2011-09-01 13:14:30 +00:00
|
|
|
} overlay_neighbour;
|
2011-09-05 07:00:50 +00:00
|
|
|
extern overlay_neighbour *overlay_neighbours;
|
2011-09-01 13:14:30 +00:00
|
|
|
|
2011-08-29 06:50:27 +00:00
|
|
|
long long overlay_gettime_ms();
|
|
|
|
int overlay_route_init(int mb_ram);
|
2012-07-02 03:49:54 +00:00
|
|
|
int overlay_route_saw_selfannounce_ack(overlay_frame *f,long long now);
|
2011-09-04 07:08:54 +00:00
|
|
|
int overlay_route_recalc_node_metrics(overlay_node *n,long long now);
|
|
|
|
int overlay_route_recalc_neighbour_metrics(overlay_neighbour *n,long long now);
|
2012-07-02 03:49:54 +00:00
|
|
|
int overlay_route_saw_selfannounce(overlay_frame *f,long long now);
|
2012-07-03 08:07:03 +00:00
|
|
|
overlay_node *overlay_route_find_node(const unsigned char *sid,int prefixLen,int createP);
|
|
|
|
unsigned int overlay_route_hash_sid(const unsigned char *sid);
|
2011-08-17 19:00:13 +00:00
|
|
|
int overlay_route_init(int mb_ram);
|
2011-09-05 05:28:12 +00:00
|
|
|
overlay_neighbour *overlay_route_get_neighbour_structure(unsigned char *packed_sid,
|
2012-05-17 07:37:46 +00:00
|
|
|
int prefixLen,int createP);
|
2011-09-05 02:49:53 +00:00
|
|
|
unsigned char *overlay_get_my_sid();
|
|
|
|
int overlay_frame_set_me_as_source(overlay_frame *f);
|
2011-09-05 06:25:59 +00:00
|
|
|
int overlay_frame_set_neighbour_as_source(overlay_frame *f,overlay_neighbour *n);
|
|
|
|
int overlay_frame_set_neighbour_as_destination(overlay_frame *f,overlay_neighbour *n);
|
2012-03-21 02:27:24 +00:00
|
|
|
int overlay_frame_set_broadcast_as_destination(overlay_frame *f);
|
|
|
|
int overlay_broadcast_generate_address(unsigned char *a);
|
2011-09-05 02:49:53 +00:00
|
|
|
int packetEncipher(unsigned char *packet,int maxlen,int *len,int cryptoflags);
|
2011-09-05 03:04:54 +00:00
|
|
|
int overlayServerMode();
|
2012-04-28 08:39:58 +00:00
|
|
|
int overlay_payload_enqueue(int q,overlay_frame *p,int forceBroadcastP);
|
2011-09-05 03:49:00 +00:00
|
|
|
long long overlay_time_in_ms();
|
2011-09-05 07:00:50 +00:00
|
|
|
int overlay_abbreviate_lookup_sender_id();
|
2012-04-29 02:26:47 +00:00
|
|
|
int overlay_route_record_link(long long now,unsigned char *to,
|
|
|
|
unsigned char *via,int sender_interface,
|
|
|
|
unsigned int s1,unsigned int s2,int score,int gateways_en_route);
|
2011-09-12 14:19:55 +00:00
|
|
|
int overlay_route_dump();
|
2011-09-12 15:44:09 +00:00
|
|
|
int overlay_route_tick_neighbour(int neighbour_id,long long now);
|
|
|
|
int overlay_route_tick_node(int bin,int slot,long long now);
|
2012-07-02 03:49:54 +00:00
|
|
|
int overlay_route_add_advertisements(overlay_buffer *e);
|
2011-09-12 19:22:52 +00:00
|
|
|
int ovleray_route_please_advertise(overlay_node *n);
|
|
|
|
int overlay_abbreviate_set_current_sender(unsigned char *in);
|
|
|
|
|
|
|
|
extern int overlay_bin_count;
|
|
|
|
extern int overlay_bin_size; /* associativity, i.e., entries per bin */
|
|
|
|
extern int overlay_bin_bytes;
|
|
|
|
extern overlay_node **overlay_nodes;
|
2011-09-12 20:07:24 +00:00
|
|
|
|
|
|
|
int overlay_route_saw_advertisements(int i,overlay_frame *f, long long now);
|
2012-01-08 22:47:54 +00:00
|
|
|
int overlay_rhizome_saw_advertisements(int i,overlay_frame *f, long long now);
|
2011-09-12 20:10:23 +00:00
|
|
|
int overlay_route_please_advertise(overlay_node *n);
|
2011-12-22 11:28:18 +00:00
|
|
|
int rhizome_server_get_fds(struct pollfd *fds,int *fdcount,int fdmax);
|
2012-05-22 03:35:29 +00:00
|
|
|
int rhizome_saw_voice_traffic();
|
2012-07-02 03:49:54 +00:00
|
|
|
int overlay_saw_mdp_containing_frame(overlay_frame *f,long long now);
|
2011-10-16 21:41:05 +00:00
|
|
|
|
|
|
|
#include "nacl.h"
|
2012-01-09 05:58:44 +00:00
|
|
|
|
2012-01-10 03:35:26 +00:00
|
|
|
int serval_packetvisualise(FILE *f,char *message,unsigned char *packet,int plen);
|
2012-01-10 11:26:07 +00:00
|
|
|
|
|
|
|
int overlay_broadcast_drop_check(unsigned char *a);
|
|
|
|
int overlay_address_is_broadcast(unsigned char *a);
|
|
|
|
int overlay_broadcast_generate_address(unsigned char *a);
|
2012-01-10 20:46:22 +00:00
|
|
|
int overlay_abbreviate_unset_current_sender();
|
2012-02-15 13:08:23 +00:00
|
|
|
int rhizome_fetching_get_fds(struct pollfd *fds,int *fdcount,int fdmax);
|
2012-03-04 22:57:31 +00:00
|
|
|
int rhizome_opendb();
|
2012-01-10 11:26:07 +00:00
|
|
|
|
2012-02-16 14:08:33 +00:00
|
|
|
typedef struct dna_identity_status {
|
2012-03-13 08:01:29 +00:00
|
|
|
char sid[SID_STRLEN];
|
2012-02-16 14:08:33 +00:00
|
|
|
char did[64+1];
|
|
|
|
char name[255+1];
|
|
|
|
|
|
|
|
int initialisedP;
|
|
|
|
time_t startofvalidity;
|
|
|
|
time_t endofvalidity;
|
|
|
|
int verifier_count;
|
|
|
|
/* Dynamically allocate these so that we don't waste a memory
|
|
|
|
(well, if we are talking about running on a feature phone, 4KB per entry
|
|
|
|
(16*256 bytes) is best avoided if we can.) */
|
|
|
|
unsigned char *verifiers[MAX_SIGNATURES];
|
2012-03-13 01:54:57 +00:00
|
|
|
int verificationStatus;
|
|
|
|
|
|
|
|
/* Set if we know that there are no duplicates of this DID/name
|
|
|
|
combination, as it allows us to avoid a database lookup. */
|
|
|
|
int uniqueDidAndName;
|
2012-02-16 14:08:33 +00:00
|
|
|
} dna_identity_status;
|
|
|
|
|
2012-07-24 06:09:36 +00:00
|
|
|
int parseCommandLine(const char *argv0, int argc, const char *const *argv);
|
2012-02-23 02:09:31 +00:00
|
|
|
|
2012-03-16 22:32:37 +00:00
|
|
|
dna_identity_status *dnacache_lookup(char *did,char *name,char *sid);
|
|
|
|
dna_identity_status *dnacache_lookup_next();
|
2012-02-16 14:08:33 +00:00
|
|
|
int dnacache_update_verification(char *did,char *sid,char *name,
|
|
|
|
char *signature,int revokeVerificationP);
|
|
|
|
int dnacache_vouch_for_identity(char *did,char *sid,char *name);
|
|
|
|
|
|
|
|
#undef DEBUG_MEM_ABUSE
|
2012-02-15 13:08:23 +00:00
|
|
|
#ifdef DEBUG_MEM_ABUSE
|
|
|
|
int memabuseInit();
|
2012-02-16 14:08:33 +00:00
|
|
|
int _memabuseCheck(const char *func,const char *file,const int line);
|
|
|
|
#define memabuseCheck() _memabuseCheck(__FUNCTION__,__FILE__,__LINE__)
|
2012-02-15 13:08:23 +00:00
|
|
|
#else
|
|
|
|
#define memabuseInit() /* */
|
2012-02-16 14:08:33 +00:00
|
|
|
#define memabuseCheck() /* */
|
2012-02-15 13:08:23 +00:00
|
|
|
#endif
|
2012-03-16 22:32:37 +00:00
|
|
|
|
2012-04-23 07:42:10 +00:00
|
|
|
const char *thisinstancepath;
|
|
|
|
const char *serval_instancepath();
|
2012-03-29 03:37:07 +00:00
|
|
|
int form_serval_instance_path(char * buf, size_t bufsiz, const char *path);
|
2012-03-29 04:33:17 +00:00
|
|
|
int create_serval_instance_dir();
|
2012-03-29 03:37:07 +00:00
|
|
|
|
2012-03-17 02:32:09 +00:00
|
|
|
int overlay_mdp_get_fds(struct pollfd *fds,int *fdcount,int fdmax);
|
2012-04-19 12:23:40 +00:00
|
|
|
int overlay_mdp_reply_error(int sock,
|
|
|
|
struct sockaddr_un *recvaddr,int recvaddrlen,
|
|
|
|
int error_number,char *message);
|
2012-07-02 03:49:54 +00:00
|
|
|
extern struct sched_ent mdp_abstract;
|
|
|
|
extern struct sched_ent mdp_named;
|
2012-04-19 12:23:40 +00:00
|
|
|
|
2012-03-19 05:36:34 +00:00
|
|
|
|
|
|
|
typedef struct sockaddr_mdp {
|
|
|
|
unsigned char sid[SID_SIZE];
|
|
|
|
unsigned int port;
|
|
|
|
} sockaddr_mdp;
|
2012-04-13 16:44:41 +00:00
|
|
|
unsigned char *keyring_get_nm_bytes(sockaddr_mdp *priv,sockaddr_mdp *pub);
|
2012-03-19 05:36:34 +00:00
|
|
|
|
2012-04-10 03:25:46 +00:00
|
|
|
typedef struct overlay_mdp_data_frame {
|
2012-03-27 08:55:38 +00:00
|
|
|
sockaddr_mdp src;
|
2012-03-19 05:36:34 +00:00
|
|
|
sockaddr_mdp dst;
|
|
|
|
unsigned short payload_length;
|
2012-04-10 03:25:46 +00:00
|
|
|
unsigned char payload[MDP_MTU-100];
|
2012-03-28 00:58:04 +00:00
|
|
|
} overlay_mdp_data_frame;
|
2012-03-19 05:36:34 +00:00
|
|
|
|
|
|
|
typedef struct overlay_mdp_bind_request {
|
|
|
|
unsigned int port_number;
|
2012-03-20 06:41:58 +00:00
|
|
|
unsigned char sid[SID_SIZE];
|
2012-03-19 05:36:34 +00:00
|
|
|
} overlay_mdp_bind_request;
|
|
|
|
|
|
|
|
typedef struct overlay_mdp_error {
|
|
|
|
unsigned int error;
|
2012-03-20 06:41:58 +00:00
|
|
|
char message[128];
|
2012-03-19 05:36:34 +00:00
|
|
|
} overlay_mdp_error;
|
|
|
|
|
2012-03-27 08:55:38 +00:00
|
|
|
typedef struct overlay_mdp_addrlist {
|
2012-07-04 02:36:15 +00:00
|
|
|
int mode;
|
2012-03-27 08:55:38 +00:00
|
|
|
unsigned int server_sid_count;
|
|
|
|
unsigned int first_sid;
|
|
|
|
unsigned int last_sid;
|
2012-07-04 02:36:15 +00:00
|
|
|
unsigned int frame_sid_count; /* how many of the following 59 slots are populated */
|
2012-03-27 08:55:38 +00:00
|
|
|
unsigned char sids[MDP_MAX_SID_REQUEST][SID_SIZE];
|
|
|
|
} overlay_mdp_addrlist;
|
|
|
|
|
2012-04-23 23:41:57 +00:00
|
|
|
/* elements sorted by size for alignment */
|
2012-04-18 23:04:57 +00:00
|
|
|
typedef struct overlay_mdp_vompevent {
|
2012-04-19 19:49:42 +00:00
|
|
|
/* Once a call has been established, this is how the MDP/VoMP server
|
|
|
|
and user-end process talk about the call. */
|
|
|
|
unsigned int call_session_token;
|
2012-04-18 23:04:57 +00:00
|
|
|
unsigned long long audio_sample_endtime;
|
2012-04-23 23:41:57 +00:00
|
|
|
unsigned long long audio_sample_starttime;
|
2012-04-18 23:04:57 +00:00
|
|
|
unsigned long long last_activity;
|
|
|
|
unsigned int flags;
|
|
|
|
unsigned short audio_sample_bytes;
|
2012-04-23 23:41:57 +00:00
|
|
|
unsigned char audio_sample_codec;
|
2012-04-18 23:04:57 +00:00
|
|
|
unsigned char local_state;
|
|
|
|
unsigned char remote_state;
|
2012-04-23 04:25:17 +00:00
|
|
|
/* list of codecs the registering party is willing to support
|
|
|
|
(for VOMPEVENT_REGISTERINTEREST) */
|
|
|
|
unsigned char supported_codecs[257];
|
2012-04-19 19:49:42 +00:00
|
|
|
union {
|
|
|
|
struct {
|
|
|
|
/* Used to precisely define the call end points during call
|
|
|
|
setup. */
|
2012-04-21 23:18:23 +00:00
|
|
|
char local_did[64];
|
|
|
|
char remote_did[64];
|
2012-04-19 19:49:42 +00:00
|
|
|
unsigned char local_sid[SID_SIZE];
|
|
|
|
unsigned char remote_sid[SID_SIZE];
|
2012-04-19 20:14:51 +00:00
|
|
|
/* session numbers of other calls in progress
|
|
|
|
(for VOMPEVENT_CALLINFO) */
|
|
|
|
unsigned int other_calls_sessions[VOMP_MAX_CALLS];
|
|
|
|
unsigned char other_calls_states[VOMP_MAX_CALLS];
|
2012-04-19 19:49:42 +00:00
|
|
|
};
|
2012-04-23 04:25:17 +00:00
|
|
|
unsigned char audio_bytes[MAX_AUDIO_BYTES];
|
2012-04-19 19:49:42 +00:00
|
|
|
};
|
2012-04-18 23:04:57 +00:00
|
|
|
} overlay_mdp_vompevent;
|
|
|
|
|
2012-04-25 21:44:01 +00:00
|
|
|
typedef struct overlay_mdp_nodeinfo {
|
|
|
|
unsigned char sid[SID_SIZE];
|
|
|
|
int sid_prefix_length; /* allow wildcard matching */
|
|
|
|
char did[64];
|
2012-05-01 05:08:09 +00:00
|
|
|
char name[64];
|
2012-04-25 21:44:01 +00:00
|
|
|
int foundP;
|
|
|
|
int localP;
|
|
|
|
int neighbourP;
|
|
|
|
int score;
|
|
|
|
int interface_number;
|
|
|
|
int resolve_did;
|
|
|
|
unsigned long long time_since_last_observation;
|
|
|
|
int index; /* which record to return or was returned (incase there are multiple matches) */
|
|
|
|
int count; /* number of matching records */
|
|
|
|
} overlay_mdp_nodeinfo;
|
|
|
|
|
2012-03-19 05:36:34 +00:00
|
|
|
typedef struct overlay_mdp_frame {
|
|
|
|
unsigned int packetTypeAndFlags;
|
|
|
|
union {
|
2012-03-28 00:58:04 +00:00
|
|
|
overlay_mdp_data_frame out;
|
|
|
|
overlay_mdp_data_frame in;
|
2012-03-19 05:36:34 +00:00
|
|
|
overlay_mdp_bind_request bind;
|
2012-03-27 08:55:38 +00:00
|
|
|
overlay_mdp_addrlist addrlist;
|
2012-04-18 23:04:57 +00:00
|
|
|
overlay_mdp_vompevent vompevent;
|
2012-04-25 21:44:01 +00:00
|
|
|
overlay_mdp_nodeinfo nodeinfo;
|
2012-03-19 05:36:34 +00:00
|
|
|
overlay_mdp_error error;
|
|
|
|
/* 2048 is too large (causes EMSGSIZE errors on OSX, but probably fine on
|
|
|
|
Linux) */
|
2012-04-10 03:25:46 +00:00
|
|
|
char raw[MDP_MTU];
|
2012-03-19 05:36:34 +00:00
|
|
|
};
|
|
|
|
} overlay_mdp_frame;
|
|
|
|
|
2012-04-14 17:47:36 +00:00
|
|
|
int keyring_mapping_request(keyring_file *k,overlay_mdp_frame *req);
|
|
|
|
|
2012-03-28 00:58:04 +00:00
|
|
|
/* Client-side MDP function */
|
|
|
|
extern int mdp_client_socket;
|
2012-03-20 16:30:39 +00:00
|
|
|
int overlay_mdp_client_init();
|
|
|
|
int overlay_mdp_client_done();
|
2012-03-20 16:57:47 +00:00
|
|
|
int overlay_mdp_client_poll(long long timeout_ms);
|
2012-03-20 17:25:13 +00:00
|
|
|
int overlay_mdp_recv(overlay_mdp_frame *mdp,int *ttl);
|
2012-03-28 00:58:04 +00:00
|
|
|
int overlay_mdp_send(overlay_mdp_frame *mdp,int flags,int timeout_ms);
|
|
|
|
|
|
|
|
/* Server-side MDP functions */
|
2012-07-02 03:49:54 +00:00
|
|
|
int overlay_saw_mdp_frame(overlay_mdp_frame *mdp,long long now);
|
2012-04-15 20:36:43 +00:00
|
|
|
int overlay_mdp_swap_src_dst(overlay_mdp_frame *mdp);
|
2012-03-27 08:55:38 +00:00
|
|
|
int overlay_mdp_reply(int sock,struct sockaddr_un *recvaddr,int recvaddrlen,
|
|
|
|
overlay_mdp_frame *mdpreply);
|
|
|
|
int overlay_mdp_relevant_bytes(overlay_mdp_frame *mdp);
|
2012-04-14 00:08:55 +00:00
|
|
|
int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
|
2012-03-28 00:58:04 +00:00
|
|
|
struct sockaddr_un *recvaddr,int recvaddlen);
|
2012-07-20 08:47:43 +00:00
|
|
|
int overlay_mdp_dnalookup_reply(const overlay_mdp_data_frame *mdpd, const unsigned char *sid, const char *uri, const char *did, const char *name);
|
2012-03-20 17:25:13 +00:00
|
|
|
|
2012-04-15 20:36:43 +00:00
|
|
|
int dump_payload(overlay_frame *p,char *message);
|
|
|
|
|
2012-04-13 16:44:41 +00:00
|
|
|
int urandombytes(unsigned char *x,unsigned long long xlen);
|
|
|
|
|
2012-03-22 06:45:51 +00:00
|
|
|
#ifdef MALLOC_PARANOIA
|
2012-03-22 06:40:27 +00:00
|
|
|
#define malloc(X) _serval_debug_malloc(X,__FILE__,__FUNCTION__,__LINE__)
|
|
|
|
#define calloc(X,Y) _serval_debug_calloc(X,Y,__FILE__,__FUNCTION__,__LINE__)
|
|
|
|
#define free(X) _serval_debug_free(X,__FILE__,__FUNCTION__,__LINE__)
|
|
|
|
|
|
|
|
void *_serval_debug_malloc(unsigned int bytes,char *file,const char *func,int line);
|
|
|
|
void *_serval_debug_calloc(unsigned int bytes,unsigned int count,char *file,const char *func,int line);
|
|
|
|
void _serval_debug_free(void *p,char *file,const char *func,int line);
|
2012-03-22 06:45:51 +00:00
|
|
|
#endif
|
2012-04-18 22:04:12 +00:00
|
|
|
|
|
|
|
|
|
|
|
typedef struct vomp_call_half {
|
|
|
|
unsigned char sid[SID_SIZE];
|
2012-04-19 19:49:42 +00:00
|
|
|
unsigned char did[64];
|
2012-04-18 22:04:12 +00:00
|
|
|
unsigned char state;
|
|
|
|
unsigned char codec;
|
|
|
|
unsigned int session;
|
|
|
|
unsigned int sequence;
|
|
|
|
/* the following is from call creation, not start of audio flow */
|
|
|
|
unsigned long long milliseconds_since_call_start;
|
|
|
|
} vomp_call_half;
|
|
|
|
|
2012-04-24 11:19:59 +00:00
|
|
|
typedef struct vomp_sample_block {
|
|
|
|
unsigned int codec;
|
|
|
|
unsigned long long starttime;
|
|
|
|
unsigned long long endtime;
|
|
|
|
unsigned char bytes[1024];
|
|
|
|
} vomp_sample_block;
|
|
|
|
|
2012-04-21 11:51:26 +00:00
|
|
|
typedef struct vomp_call_state {
|
2012-07-03 05:43:39 +00:00
|
|
|
struct sched_ent alarm;
|
2012-04-18 22:04:12 +00:00
|
|
|
vomp_call_half local;
|
|
|
|
vomp_call_half remote;
|
2012-07-05 06:22:21 +00:00
|
|
|
int initiated_call;
|
2012-04-18 22:04:12 +00:00
|
|
|
int ringing;
|
2012-05-10 22:30:09 +00:00
|
|
|
int fast_audio;
|
2012-04-19 22:32:03 +00:00
|
|
|
unsigned long long create_time;
|
2012-04-18 22:04:12 +00:00
|
|
|
unsigned long long last_activity;
|
2012-04-24 20:08:45 +00:00
|
|
|
unsigned long long audio_clock;
|
2012-04-18 22:04:12 +00:00
|
|
|
int audio_started;
|
2012-07-05 06:22:21 +00:00
|
|
|
// last local & remote status we sent to all interested parties
|
2012-04-21 11:06:26 +00:00
|
|
|
int last_sent_status;
|
2012-04-23 04:00:22 +00:00
|
|
|
unsigned char remote_codec_list[256];
|
2012-04-24 11:19:59 +00:00
|
|
|
int recent_sample_rotor;
|
|
|
|
vomp_sample_block recent_samples[VOMP_MAX_RECENT_SAMPLES];
|
2012-07-05 06:22:21 +00:00
|
|
|
|
|
|
|
int sample_pos;
|
|
|
|
unsigned int seen_samples[VOMP_MAX_RECENT_SAMPLES *4];
|
2012-04-18 22:04:12 +00:00
|
|
|
} vomp_call_state;
|
|
|
|
|
2012-05-02 17:30:34 +00:00
|
|
|
extern int vomp_call_count;
|
|
|
|
extern int vomp_active_call;
|
|
|
|
extern vomp_call_state vomp_call_states[VOMP_MAX_CALLS];
|
|
|
|
|
|
|
|
|
2012-05-02 16:58:39 +00:00
|
|
|
vomp_call_state *vomp_find_call_by_session(int session_token);
|
2012-04-18 23:17:59 +00:00
|
|
|
int vomp_mdp_event(overlay_mdp_frame *mdp,
|
|
|
|
struct sockaddr_un *recvaddr,int recvaddrlen);
|
|
|
|
int vomp_mdp_received(overlay_mdp_frame *mdp);
|
2012-04-20 23:37:36 +00:00
|
|
|
char *vomp_describe_state(int state);
|
2012-04-23 07:22:10 +00:00
|
|
|
char *vomp_describe_codec(int c);
|
2012-04-21 11:51:26 +00:00
|
|
|
int vomp_tick_interval();
|
2012-04-24 05:57:20 +00:00
|
|
|
int vomp_sample_size(int c);
|
2012-04-24 11:19:59 +00:00
|
|
|
int vomp_codec_timespan(int c);
|
2012-05-03 18:14:41 +00:00
|
|
|
int vomp_parse_dtmf_digit(char c);
|
2012-07-05 06:22:21 +00:00
|
|
|
int vomp_dial(unsigned char *local_sid, unsigned char *remote_sid, char *local_did, char *remote_did);
|
|
|
|
int vomp_pickup(vomp_call_state *call);
|
|
|
|
int vomp_hangup(vomp_call_state *call);
|
2012-07-06 00:44:39 +00:00
|
|
|
int vomp_send_status_remote_audio(vomp_call_state *call, int audio_codec, const unsigned char *audio, int audio_length);
|
2012-07-05 06:22:21 +00:00
|
|
|
|
2012-04-20 06:11:13 +00:00
|
|
|
|
|
|
|
typedef struct command_line_option {
|
2012-04-23 07:42:10 +00:00
|
|
|
int (*function)(int argc, const char *const *argv, struct command_line_option *o);
|
2012-05-03 05:08:30 +00:00
|
|
|
const char *words[32]; // 32 words should be plenty!
|
2012-04-20 06:11:13 +00:00
|
|
|
unsigned long long flags;
|
|
|
|
#define CLIFLAG_NONOVERLAY (1<<0) /* Uses a legacy IPv4 DNA call instead of overlay mnetwork */
|
|
|
|
#define CLIFLAG_STANDALONE (1<<1) /* Cannot be issued to a running instance */
|
2012-05-03 05:08:30 +00:00
|
|
|
const char *description; // describe this invocation
|
2012-04-20 06:11:13 +00:00
|
|
|
} command_line_option;
|
|
|
|
|
|
|
|
extern command_line_option command_line_options[];
|
2012-04-23 07:42:10 +00:00
|
|
|
int cli_arg(int argc, const char *const *argv, command_line_option *o, char *argname, const char **dst, int (*validator)(const char *arg), char *defaultvalue);
|
2012-04-24 08:20:27 +00:00
|
|
|
int cli_putchar(char c);
|
|
|
|
int cli_puts(const char *str);
|
|
|
|
int cli_printf(const char *fmt, ...);
|
|
|
|
int cli_delim(const char *opt);
|
2012-04-20 06:11:13 +00:00
|
|
|
|
2012-07-04 09:27:02 +00:00
|
|
|
int is_configvarname(const char *arg);
|
|
|
|
|
2012-04-20 06:11:13 +00:00
|
|
|
int overlay_mdp_getmyaddr(int index,unsigned char *sid);
|
2012-04-25 10:54:08 +00:00
|
|
|
int overlay_mdp_bind(unsigned char *localaddr,int port);
|
2012-04-25 21:44:01 +00:00
|
|
|
int overlay_route_node_info(overlay_mdp_frame *mdp,
|
|
|
|
struct sockaddr_un *addr,int addrlen);
|
2012-06-08 07:31:50 +00:00
|
|
|
int overlay_interface_register(char *name,
|
2012-07-25 05:23:53 +00:00
|
|
|
struct sockaddr_in *local,
|
|
|
|
struct sockaddr_in *broadcast);
|
2012-05-10 04:37:11 +00:00
|
|
|
int overlay_queue_dump(overlay_txqueue *q);
|
|
|
|
int overlay_broadcast_ensemble(int interface_number,
|
|
|
|
struct sockaddr_in *recipientaddr /* NULL == broadcast */,
|
|
|
|
unsigned char *bytes,int len);
|
2012-04-20 06:11:13 +00:00
|
|
|
|
2012-04-23 07:42:10 +00:00
|
|
|
int app_vomp_status(int argc, const char *const *argv, struct command_line_option *o);
|
|
|
|
int app_vomp_dial(int argc, const char *const *argv, struct command_line_option *o);
|
|
|
|
int app_vomp_pickup(int argc, const char *const *argv, struct command_line_option *o);
|
|
|
|
int app_vomp_hangup(int argc, const char *const *argv, struct command_line_option *o);
|
|
|
|
int app_vomp_monitor(int argc, const char *const *argv, struct command_line_option *o);
|
2012-04-23 11:28:28 +00:00
|
|
|
#ifdef HAVE_VOIPTEST
|
|
|
|
int app_pa_phone(int argc, const char *const *argv, struct command_line_option *o);
|
|
|
|
#endif
|
2012-04-24 02:44:53 +00:00
|
|
|
int app_vomp_dtmf(int argc, const char *const *argv, struct command_line_option *o);
|
2012-05-08 05:10:39 +00:00
|
|
|
int app_monitor_cli(int argc, const char *const *argv, struct command_line_option *o);
|
2012-05-02 16:58:39 +00:00
|
|
|
|
|
|
|
int monitor_get_fds(struct pollfd *fds,int *fdcount,int fdmax);
|
|
|
|
|
|
|
|
int monitor_setup_sockets();
|
|
|
|
int monitor_get_fds(struct pollfd *fds,int *fdcount,int fdmax);
|
2012-05-02 17:30:34 +00:00
|
|
|
int monitor_call_status(vomp_call_state *call);
|
2012-07-05 06:22:21 +00:00
|
|
|
int monitor_send_audio(vomp_call_state *call, int audio_codec, unsigned int start_time, unsigned int end_time, const unsigned char *audio, int audio_length);
|
2012-07-03 08:07:03 +00:00
|
|
|
int monitor_announce_peer(const unsigned char *sid);
|
2012-07-17 08:52:39 +00:00
|
|
|
int monitor_announce_unreachable_peer(const unsigned char *sid);
|
2012-06-25 05:30:07 +00:00
|
|
|
int monitor_tell_clients(char *msg, int msglen, int mask);
|
2012-05-02 17:30:34 +00:00
|
|
|
extern int monitor_socket_count;
|
2012-05-09 18:16:27 +00:00
|
|
|
|
2012-05-10 07:28:25 +00:00
|
|
|
|
|
|
|
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();
|
2012-05-10 22:30:09 +00:00
|
|
|
monitor_audio *audio_reflector_detect();
|
2012-05-09 18:16:27 +00:00
|
|
|
int detectAudioDevice();
|
2012-05-10 08:59:00 +00:00
|
|
|
int getAudioPlayFd();
|
|
|
|
int getAudioRecordFd();
|
2012-05-09 18:16:27 +00:00
|
|
|
int getAudioBytes(unsigned char *buffer,
|
|
|
|
int offset,
|
|
|
|
int bufferSize);
|
|
|
|
int encodeAndDispatchRecordedAudio(int fd,int callSessionToken,
|
|
|
|
int recordCodec,
|
|
|
|
unsigned char *sampleData,
|
|
|
|
int sampleBytes);
|
2012-05-10 04:37:11 +00:00
|
|
|
int scrapeProcNetRoute();
|
2012-05-28 05:24:33 +00:00
|
|
|
int lsif();
|
2012-06-08 07:01:59 +00:00
|
|
|
int doifaddrs();
|
2012-05-10 22:30:09 +00:00
|
|
|
int bufferAudioForPlayback(int codec,long long start_time,long long end_time,
|
|
|
|
unsigned char *data,int dataLen);
|
|
|
|
int startAudio();
|
|
|
|
int stopAudio();
|
2012-05-21 11:15:07 +00:00
|
|
|
|
|
|
|
#define SERVER_UNKNOWN 1
|
|
|
|
#define SERVER_NOTRESPONDING 2
|
|
|
|
#define SERVER_NOTRUNNING 3
|
|
|
|
#define SERVER_RUNNING 4
|
|
|
|
int server_probe(int *pid);
|
2012-06-20 22:37:03 +00:00
|
|
|
|
2012-07-20 08:47:43 +00:00
|
|
|
int dna_helper_shutdown();
|
|
|
|
int dna_helper_enqueue(overlay_mdp_frame *mdp, const char *did, const unsigned char *requestorSid);
|
2012-06-20 22:37:03 +00:00
|
|
|
int dna_return_resolution(overlay_mdp_frame *mdp, unsigned char *fromSid,
|
|
|
|
const char *did,const char *name,const char *uri);
|
2012-07-23 08:59:57 +00:00
|
|
|
int parseDnaReply(const char *buf, size_t len, char *token, char *did, char *name, char *uri, const char **bufp);
|
2012-06-21 01:00:08 +00:00
|
|
|
extern int sigPipeFlag;
|
|
|
|
extern int sigIoFlag;
|
|
|
|
void sigPipeHandler(int signal);
|
|
|
|
void sigIoHandler(int signal);
|
2012-06-21 05:05:05 +00:00
|
|
|
|
2012-07-10 09:21:41 +00:00
|
|
|
#define set_nonblock(fd) (_set_nonblock(fd, __FILE__, __LINE__, __FUNCTION__))
|
|
|
|
#define set_block(fd) (_set_block(fd, __FILE__, __LINE__, __FUNCTION__))
|
2012-07-13 01:34:50 +00:00
|
|
|
#define read_nonblock(fd,buf,len) (_read_nonblock(fd, buf, len, __FILE__, __LINE__, __FUNCTION__))
|
2012-07-10 09:21:41 +00:00
|
|
|
#define write_all(fd,buf,len) (_write_all(fd, buf, len, __FILE__, __LINE__, __FUNCTION__))
|
|
|
|
#define write_nonblock(fd,buf,len) (_write_nonblock(fd, buf, len, __FILE__, __LINE__, __FUNCTION__))
|
|
|
|
#define write_all_nonblock(fd,buf,len) (_write_all_nonblock(fd, buf, len, __FILE__, __LINE__, __FUNCTION__))
|
|
|
|
#define write_str(fd,str) (_write_str(fd, str, __FILE__, __LINE__, __FUNCTION__))
|
|
|
|
#define write_str_nonblock(fd,str) (_write_str_nonblock(fd, str, __FILE__, __LINE__, __FUNCTION__))
|
|
|
|
|
|
|
|
int _set_nonblock(int fd, const char *file, unsigned int line, const char *function);
|
|
|
|
int _set_block(int fd, const char *file, unsigned int line, const char *function);
|
2012-07-19 08:29:45 +00:00
|
|
|
ssize_t _read_nonblock(int fd, void *buf, size_t len, const char *file, unsigned int line, const char *function);
|
|
|
|
ssize_t _write_all(int fd, const void *buf, size_t len, const char *file, unsigned int line, const char *function);
|
|
|
|
ssize_t _write_nonblock(int fd, const void *buf, size_t len, const char *file, unsigned int line, const char *function);
|
|
|
|
ssize_t _write_all_nonblock(int fd, const void *buf, size_t len, const char *file, unsigned int line, const char *function);
|
|
|
|
ssize_t _write_str(int fd, const char *str, const char *file, unsigned int line, const char *function);
|
|
|
|
ssize_t _write_str_nonblock(int fd, const char *str, const char *file, unsigned int line, const char *function);
|
2012-06-25 06:37:11 +00:00
|
|
|
|
2012-07-03 00:56:22 +00:00
|
|
|
int rhizome_http_server_start();
|
2012-06-25 23:52:51 +00:00
|
|
|
int overlay_mdp_setup_sockets();
|
|
|
|
|
2012-07-02 03:49:54 +00:00
|
|
|
int schedule(struct sched_ent *alarm);
|
|
|
|
int unschedule(struct sched_ent *alarm);
|
|
|
|
int watch(struct sched_ent *alarm);
|
|
|
|
int unwatch(struct sched_ent *alarm);
|
2012-06-22 03:55:41 +00:00
|
|
|
int fd_poll();
|
2012-07-02 03:49:54 +00:00
|
|
|
|
|
|
|
void overlay_interface_discover(struct sched_ent *alarm);
|
|
|
|
void overlay_dummy_poll(struct sched_ent *alarm);
|
|
|
|
void overlay_route_tick(struct sched_ent *alarm);
|
|
|
|
void rhizome_enqueue_suggestions(struct sched_ent *alarm);
|
|
|
|
void server_shutdown_check(struct sched_ent *alarm);
|
|
|
|
void overlay_mdp_poll(struct sched_ent *alarm);
|
|
|
|
void fd_periodicstats(struct sched_ent *alarm);
|
|
|
|
void rhizome_check_connections(struct sched_ent *alarm);
|
|
|
|
|
|
|
|
void monitor_client_poll(struct sched_ent *alarm);
|
|
|
|
void monitor_poll(struct sched_ent *alarm);
|
|
|
|
void overlay_interface_poll(struct sched_ent *alarm);
|
|
|
|
void rhizome_client_poll(struct sched_ent *alarm);
|
|
|
|
void rhizome_fetch_poll(struct sched_ent *alarm);
|
|
|
|
void rhizome_server_poll(struct sched_ent *alarm);
|
|
|
|
|
|
|
|
/* function timing routines */
|
2012-07-03 08:30:52 +00:00
|
|
|
int fd_clearstats();
|
|
|
|
int fd_showstats();
|
2012-06-22 03:55:41 +00:00
|
|
|
int fd_checkalarms();
|
2012-07-12 00:45:16 +00:00
|
|
|
int fd_func_exit(struct call_stats *this_call);
|
2012-07-02 03:49:54 +00:00
|
|
|
int fd_func_enter(struct call_stats *this_call);
|
2012-07-12 00:45:16 +00:00
|
|
|
void dump_stack();
|
|
|
|
|
|
|
|
#define IN() static struct profile_total _aggregate_stats={NULL,0,__FUNCTION__,0,0,0}; \
|
|
|
|
struct call_stats _this_call; \
|
|
|
|
_this_call.totals=&_aggregate_stats; \
|
|
|
|
fd_func_enter(&_this_call);
|
2012-07-02 03:49:54 +00:00
|
|
|
|
2012-07-12 00:45:16 +00:00
|
|
|
#define OUT() fd_func_exit(&_this_call);
|
2012-06-25 23:52:51 +00:00
|
|
|
#define RETURN(X) { OUT() return(X); }
|