#include "../src/meshlink.h"
static void log_message(meshlink_handle_t *mesh, meshlink_log_level_t level, const char *text) {
- const char *levelstr[] = {"DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"};
- fprintf(stderr, "%s: %s\n", levelstr[level], text);
+ const char *levelstr[] = {
+ [MESHLINK_DEBUG] = "\x1b[34mDEBUG",
+ [MESHLINK_INFO] = "\x1b[32mINFO",
+ [MESHLINK_WARNING] = "\x1b[33mWARNING",
+ [MESHLINK_ERROR] = "\x1b[31mERROR",
+ [MESHLINK_CRITICAL] = "\x1b[31mCRITICAL",
+ };
+ fprintf(stderr, "%s:\x1b[0m %s\n", levelstr[level], text);
}
static void receive(meshlink_handle_t *mesh, meshlink_node_t *source, const void *data, size_t len) {
if(argc > 2)
nick = argv[2];
+ meshlink_set_log_cb(NULL, MESHLINK_INFO, log_message);
+
meshlink_handle_t *mesh = meshlink_open(confbase, nick, "chat");
if(!mesh) {
fprintf(stderr, "Could not open MeshLink: %s\n", meshlink_strerror(meshlink_errno));
if(!node) {
fprintf(stderr, "Unknown node '%s'\n", arg);
} else {
- printf("Node %s found\n", arg);
+ printf("Node %s found, pmtu %zd\n", arg, meshlink_get_pmtu(mesh[0], node));
}
}
} else if(!strcasecmp(buf, "link")) {
return true;
}
- logger(DEBUG_ALWAYS, LOG_ERR, "\"yes\" or \"no\" expected for configuration variable %s in %s line %d",
+ logger(NULL, MESHLINK_ERROR, "\"yes\" or \"no\" expected for configuration variable %s in %s line %d",
cfg->variable, cfg->file, cfg->line);
return false;
if(sscanf(cfg->value, "%d", result) == 1)
return true;
- logger(DEBUG_ALWAYS, LOG_ERR, "Integer expected for configuration variable %s in %s line %d",
+ logger(NULL, MESHLINK_ERROR, "Integer expected for configuration variable %s in %s line %d",
cfg->variable, cfg->file, cfg->line);
return false;
return true;
}
- logger(DEBUG_ALWAYS, LOG_ERR, "Hostname or IP address expected for configuration variable %s in %s line %d",
+ logger(NULL, MESHLINK_ERROR, "Hostname or IP address expected for configuration variable %s in %s line %d",
cfg->variable, cfg->file, cfg->line);
return false;
if(!*value) {
const char err[] = "No value for variable";
- logger(DEBUG_ALWAYS, LOG_ERR, "%s `%s' on line %d while reading config file %s",
+ logger(NULL, MESHLINK_ERROR, "%s `%s' on line %d while reading config file %s",
err, variable, lineno, fname);
return NULL;
}
fp = fopen(fname, "r");
if(!fp) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Cannot open config file %s: %s", fname, strerror(errno));
+ logger(NULL, MESHLINK_ERROR, "Cannot open config file %s: %s", fname, strerror(errno));
return false;
}
x = read_config_file(mesh->config, filename);
if(!x && errno)
- logger(DEBUG_ALWAYS, LOG_ERR, "Failed to read `%s': %s", filename, strerror(errno));
+ logger(mesh, MESHLINK_ERROR, "Failed to read `%s': %s", filename, strerror(errno));
return x;
}
FILE *fp = fopen(filename, "a");
if(!fp) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Cannot open config file %s: %s", filename, strerror(errno));
+ logger(mesh, MESHLINK_ERROR, "Cannot open config file %s: %s", filename, strerror(errno));
} else {
fprintf(fp, "%s = %s\n", key, value);
fclose(fp);
{
case AVAHI_ENTRY_GROUP_ESTABLISHED:
/* The entry group has been established successfully */
- fprintf(stderr, "Service successfully established.\n");
+ logger(mesh, MESHLINK_DEBUG, "Avahi Service successfully established.\n");
break;
case AVAHI_ENTRY_GROUP_COLLISION:
- fprintf(stderr, "Service collision\n");
+ logger(mesh, MESHLINK_WARNING, "Avahi Service collision.\n");
// @TODO can we just set a new name and retry?
break;
case AVAHI_ENTRY_GROUP_FAILURE :
/* Some kind of failure happened while we were registering our services */
- fprintf(stderr, "Entry group failure: %s\n", avahi_strerror(avahi_server_errno(mesh->avahi_server)));
+ logger(mesh, MESHLINK_ERROR, "Avahi Entry group failure: %s\n", avahi_strerror(avahi_server_errno(mesh->avahi_server)));
avahi_simple_poll_quit(mesh->avahi_poll);
break;
assert(mesh->avahi_servicetype != NULL);
assert(mesh->self != NULL);
- fprintf(stderr, "Adding service\n");
+ logger(mesh, MESHLINK_DEBUG, "Adding service\n");
/* Ifthis is the first time we're called, let's create a new entry group */
if(!mesh->avahi_group)
{
if(!(mesh->avahi_group = avahi_s_entry_group_new(mesh->avahi_server, discovery_entry_group_callback, mesh)))
{
- fprintf(stderr, "avahi_entry_group_new() failed: %s\n", avahi_strerror(avahi_server_errno(mesh->avahi_server)));
+ logger(mesh, MESHLINK_ERROR, "avahi_entry_group_new() failed: %s\n", avahi_strerror(avahi_server_errno(mesh->avahi_server)));
goto fail;
}
}
if(txt_name == NULL)
{
- fprintf(stderr, "Could not allocate memory for TXT record\n");
+ logger(mesh, MESHLINK_ERROR, "Could not allocate memory for TXT record\n");
goto fail;
}
int ret = 0;
if((ret = avahi_server_add_service(mesh->avahi_server, mesh->avahi_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, meshlink_get_fingerprint(mesh, (meshlink_node_t *)mesh->self), mesh->avahi_servicetype, NULL, NULL, atoi(mesh->myport), txt_name, txt_fingerprint, NULL)) < 0)
{
- fprintf(stderr, "Failed to add service: %s\n", avahi_strerror(ret));
+ logger(mesh, MESHLINK_ERROR, "Failed to add service: %s\n", avahi_strerror(ret));
goto fail;
}
/* Tell the server to register the service */
if((ret = avahi_s_entry_group_commit(mesh->avahi_group)) < 0)
{
- fprintf(stderr, "Failed to commit entry_group: %s\n", avahi_strerror(ret));
+ logger(mesh, MESHLINK_ERROR, "Failed to commit entry_group: %s\n", avahi_strerror(ret));
goto fail;
}
char hostnamestr[36+1];
uuid_unparse_lower(hostname, hostnamestr);
- fprintf(stderr, "Host name collision, retrying with '%s'\n", hostnamestr);
+ logger(mesh, MESHLINK_WARNING, "Avahi host name collision, retrying with '%s'\n", hostnamestr);
int result = avahi_server_set_host_name(mesh->avahi_server, hostnamestr);
if(result < 0)
{
- fprintf(stderr, "Failed to set new host name: %s\n", avahi_strerror(result));
+ logger(mesh, MESHLINK_ERROR, "Avahi failed to set new host name: %s\n", avahi_strerror(result));
avahi_simple_poll_quit(mesh->avahi_poll);
return;
}
assert(mesh->avahi_poll != NULL);
/* Terminate on failure */
- fprintf(stderr, "Server failure: %s\n", avahi_strerror(avahi_server_errno(mesh->avahi_server)));
+ logger(mesh, MESHLINK_ERROR, "Avahi server failure: %s\n", avahi_strerror(avahi_server_errno(mesh->avahi_server)));
avahi_simple_poll_quit(mesh->avahi_poll);
}
break;
assert(type != NULL);
assert(domain != NULL);
- fprintf(stderr, "(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain, avahi_strerror(avahi_server_errno(mesh->avahi_server)));
+ logger(mesh, MESHLINK_WARNING, "(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain, avahi_strerror(avahi_server_errno(mesh->avahi_server)));
}
break;
char straddr[AVAHI_ADDRESS_STR_MAX], *strtxt;
- fprintf(stderr, "(Resolver) Service '%s' of type '%s' in domain '%s':\n", name, type, domain);
+ logger(mesh, MESHLINK_DEBUG, "(Resolver) Service '%s' of type '%s' in domain '%s':\n", name, type, domain);
avahi_address_snprint(straddr, sizeof(straddr), address);
strtxt = avahi_string_list_to_string(txt);
- fprintf(stderr,
+ logger(mesh, MESHLINK_DEBUG,
"\t%s:%u (%s)\n"
"\tTXT=%s\n"
"\tcookie is %u\n"
if(node != NULL)
{
- fprintf(stderr, "Node %s is part of the mesh network.\n", node->name);
+ logger(mesh, MESHLINK_INFO, "Node %s is part of the mesh network.\n", node->name);
sockaddr_t naddress;
memset(&naddress, 0, sizeof(naddress));
}
else
{
- fprintf(stderr, "Could not resolve node %s to a known address family type.\n", node->name);
+ logger(mesh, MESHLINK_WARNING, "Could not resolve node %s to a known address family type.\n", node->name);
}
}
else
{
- fprintf(stderr, "Node %s is not part of the mesh network.\n", node_name);
+ logger(mesh, MESHLINK_WARNING, "Node %s is not part of the mesh network.\n", node_name);
}
}
else
{
- fprintf(stderr, "TXT records invalid.\n");
+ logger(mesh, MESHLINK_WARNING, "TXT records invalid.\n");
}
}
else
{
- fprintf(stderr, "TXT records missing.\n");
+ logger(mesh, MESHLINK_WARNING, "TXT records missing.\n");
}
}
break;
{
case AVAHI_BROWSER_FAILURE:
{
- fprintf(stderr, "(Browser) %s\n", avahi_strerror(avahi_server_errno(mesh->avahi_server)));
+ logger(mesh, MESHLINK_ERROR, "(Browser) %s\n", avahi_strerror(avahi_server_errno(mesh->avahi_server)));
avahi_simple_poll_quit(mesh->avahi_poll);
}
return;
assert(type != NULL);
assert(domain != NULL);
- fprintf(stderr, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
+ logger(mesh, MESHLINK_DEBUG, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
/* We ignore the returned resolver object. In the callback
function we free it. Ifthe server is terminated before
the callback function is called the server will free
the resolver for us. */
if(!(avahi_s_service_resolver_new(mesh->avahi_server, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, discovery_resolve_callback, mesh)))
{
- fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_server_errno(mesh->avahi_server)));
+ logger(mesh, MESHLINK_DEBUG, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_server_errno(mesh->avahi_server)));
}
}
break;
assert(type != NULL);
assert(domain != NULL);
- fprintf(stderr, "(Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
+ logger(mesh, MESHLINK_DEBUG, "(Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
}
break;
case AVAHI_BROWSER_ALL_FOR_NOW:
case AVAHI_BROWSER_CACHE_EXHAUSTED:
{
- fprintf(stderr, "(Browser) %s\n", event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW");
+ logger(mesh, MESHLINK_DEBUG, "(Browser) %s\n", event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW");
}
break;
}
bool discovery_start(meshlink_handle_t *mesh)
{
- fprintf(stderr, "discovery_start called\n");
+ logger(mesh, MESHLINK_DEBUG, "discovery_start called\n");
// asserts
assert(mesh != NULL);
if(mesh->avahi_servicetype == NULL)
{
- fprintf(stderr, "Failed to allocate memory for service type string.\n");
+ logger(mesh, MESHLINK_ERROR, "Failed to allocate memory for service type string.\n");
goto fail;
}
// Allocate discovery loop object
if(!(mesh->avahi_poll = avahi_simple_poll_new()))
{
- fprintf(stderr, "Failed to create discovery poll object.\n");
+ logger(mesh, MESHLINK_ERROR, "Failed to create discovery poll object.\n");
goto fail;
}
/* Check wether creating the server object succeeded */
if(!mesh->avahi_server)
{
- fprintf(stderr, "Failed to create discovery server: %s\n", avahi_strerror(error));
+ logger(mesh, MESHLINK_ERROR, "Failed to create discovery server: %s\n", avahi_strerror(error));
goto fail;
}
// Create the service browser
if(!(mesh->avahi_browser = avahi_s_service_browser_new(mesh->avahi_server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, mesh->avahi_servicetype, NULL, 0, discovery_browse_callback, mesh)))
{
- fprintf(stderr, "Failed to create discovery service browser: %s\n", avahi_strerror(avahi_server_errno(mesh->avahi_server)));
+ logger(mesh, MESHLINK_ERROR, "Failed to create discovery service browser: %s\n", avahi_strerror(avahi_server_errno(mesh->avahi_server)));
goto fail;
}
// Start the discovery thread
if(pthread_create(&mesh->discovery_thread, NULL, discovery_loop, mesh) != 0)
{
- fprintf(stderr, "Could not start discovery thread: %s\n", strerror(errno));
+ logger(mesh, MESHLINK_ERROR, "Could not start discovery thread: %s\n", strerror(errno));
memset(&mesh->discovery_thread, 0, sizeof mesh->discovery_thread);
goto fail;
}
void discovery_stop(meshlink_handle_t *mesh)
{
- fprintf(stderr, "discovery_stop called\n");
+ logger(mesh, MESHLINK_DEBUG, "discovery_stop called\n");
// asserts
assert(mesh != NULL);
int len = strlen(p);
if(len != 43) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Invalid size %d for public key!", len);
+ logger(NULL, MESHLINK_ERROR, "Invalid size %d for public key!", len);
return 0;
}
ecdsa_t *ecdsa = xzalloc(sizeof *ecdsa);
len = b64decode(p, ecdsa->public, len);
if(len != 32) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Invalid format of public key! len = %d", len);
+ logger(NULL, MESHLINK_ERROR, "Invalid format of public key! len = %d", len);
free(ecdsa);
return 0;
}
for list_each(connection_t, c, mesh->connections)
c->status.mst = false;
- logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Running Kruskal's algorithm:");
+ logger(mesh, MESHLINK_DEBUG, "Running Kruskal's algorithm:");
/* Clear visited status on nodes */
if(e->reverse->connection)
e->reverse->connection->status.mst = true;
- logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Adding edge %s - %s weight %d", e->from->name, e->to->name, e->weight);
+ logger(mesh, MESHLINK_DEBUG, " Adding edge %s - %s weight %d", e->from->name, e->to->name, e->weight);
if(skipped) {
skipped = false;
/* Loop while todo_list is filled */
for list_each(node_t, n, todo_list) { /* "n" is the node from which we start */
- logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Examining edges from %s", n->name);
+ logger(mesh, MESHLINK_DEBUG, " Examining edges from %s", n->name);
if(n->distance < 0)
abort();
n->last_state_change = mesh->loop.now.tv_sec;
if(n->status.reachable) {
- logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became reachable",
+ logger(mesh, MESHLINK_DEBUG, "Node %s (%s) became reachable",
n->name, n->hostname);
} else {
- logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became unreachable",
+ logger(mesh, MESHLINK_DEBUG, "Node %s (%s) became unreachable",
n->name, n->hostname);
}
#include "sptps.h"
// TODO: refactor logging code to use a meshlink_handle_t *.
-void logger(int level, int priority, const char *format, ...) {
- //if(level > mesh->debug_level)
- // return;
+void logger(meshlink_handle_t *mesh, meshlink_log_level_t level, const char *format, ...) {
+ if(mesh) {
+ if(level < mesh->log_level || !mesh->log_cb)
+ return;
+ } else {
+ if(level < global_log_level || !global_log_cb)
+ return;
+ }
va_list ap;
char message[1024] = "";
if(len > 0 && len < sizeof message && message[len - 1] == '\n')
message[len - 1] = 0;
- fprintf(stderr, "%s\n", message);
+ if(mesh)
+ mesh->log_cb(mesh, level, message);
+ else
+ global_log_cb(NULL, level, message);
}
#ifndef __MESHLINK_LOGGER_H__
#define __MESHLINK_LOGGER_H__
-typedef enum debug_t {
- DEBUG_NOTHING = 0, /* Quiet mode, only show starting/stopping of the daemon */
- DEBUG_ALWAYS = 0,
- DEBUG_CONNECTIONS = 1, /* Show (dis)connects of other nodes via TCP */
- DEBUG_ERROR = 2, /* Show error messages received from other hosts */
- DEBUG_STATUS = 2, /* Show status messages received from other hosts */
- DEBUG_PROTOCOL = 3, /* Show the requests that are sent/received */
- DEBUG_META = 4, /* Show contents of every request that is sent/received */
- DEBUG_TRAFFIC = 5, /* Show network traffic information */
- DEBUG_PACKET = 6, /* Show contents of each packet that is being sent/received */
- DEBUG_SCARY_THINGS = 10 /* You have been warned */
-} debug_t;
+#include "meshlink_internal.h"
-typedef enum logmode_t {
- LOGMODE_NULL,
- LOGMODE_STDERR,
- LOGMODE_SYSLOG
-} logmode_t;
-
-#ifdef HAVE_MINGW
-#define LOG_EMERG EVENTLOG_ERROR_TYPE
-#define LOG_ALERT EVENTLOG_ERROR_TYPE
-#define LOG_CRIT EVENTLOG_ERROR_TYPE
-#define LOG_ERR EVENTLOG_ERROR_TYPE
-#define LOG_WARNING EVENTLOG_WARNING_TYPE
-#define LOG_NOTICE EVENTLOG_INFORMATION_TYPE
-#define LOG_INFO EVENTLOG_INFORMATION_TYPE
-#define LOG_DEBUG EVENTLOG_INFORMATION_TYPE
-#else
-#ifndef HAVE_SYSLOG_H
-enum {
- LOG_EMERG,
- LOG_ALERT,
- LOG_CRIT,
- LOG_ERR,
- LOG_WARNING,
- LOG_NOTICE,
- LOG_INFO,
- LOG_DEBUG,
-};
-#endif
-#endif
-
-extern void logger(int, int, const char *, ...) __attribute__ ((__format__(printf, 3, 4)));
+extern void logger(meshlink_handle_t *mesh, meshlink_log_level_t level, const char *format, ...) __attribute__ ((__format__(printf, 3, 4)));
#endif /* __MESHLINK_LOGGER_H__ */
#include "crypto.h"
#include "ecdsagen.h"
+#include "logger.h"
#include "meshlink_internal.h"
#include "netutl.h"
#include "node.h"
static pthread_mutex_t global_mutex;
__thread meshlink_errno_t meshlink_errno;
+meshlink_log_cb_t global_log_cb;
+meshlink_log_level_t global_log_level;
//TODO: this can go away completely
const var_t variables[] = {
static bool fcopy(FILE *out, const char *filename) {
FILE *in = fopen(filename, "r");
if(!in) {
- fprintf(stderr, "Could not open %s: %s\n", filename, strerror(errno));
+ logger(NULL, MESHLINK_ERROR, "Could not open %s: %s\n", filename, strerror(errno));
return false;
}
goto done;
// If that doesn't work, guess externally visible hostname
- fprintf(stderr, "Trying to discover externally visible hostname...\n");
+ logger(mesh, MESHLINK_DEBUG, "Trying to discover externally visible hostname...\n");
struct addrinfo *ai = str2addrinfo("meshlink.io", "80", SOCK_STREAM);
struct addrinfo *aip = ai;
static const char request[] = "GET http://www.meshlink.io/host.cgi HTTP/1.0\r\n\r\n";
fprintf(f, "\nAddress = %s\n", hostname);
fclose(f);
} else {
- fprintf(stderr, "Could not append Address to %s: %s\n", filename, strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Could not append Address to %s: %s\n", filename, strerror(errno));
}
done:
const char *end = strchr(*data, '\n');
size_t len = end ? end - *data : strlen(*data);
if(len >= sizeof line) {
- fprintf(stderr, "Maximum line length exceeded!\n");
+ logger(NULL, MESHLINK_ERROR, "Maximum line length exceeded!\n");
return NULL;
}
if(len && !isprint(**data))
snprintf(filename, sizeof filename, "%s" SLASH "hosts" SLASH "%s", mesh->confbase, mesh->name);
FILE *f = fopen(filename, "a");
if(!f) {
- fprintf(stderr, "Please change MeshLink's Port manually.\n");
+ logger(mesh, MESHLINK_DEBUG, "Please change MeshLink's Port manually.\n");
return 0;
}
}
}
- fprintf(stderr, "Please change MeshLink's Port manually.\n");
+ logger(mesh, MESHLINK_DEBUG, "Please change MeshLink's Port manually.\n");
return 0;
}
static bool finalize_join(meshlink_handle_t *mesh) {
char *name = xstrdup(get_value(mesh->data, "Name"));
if(!name) {
- fprintf(stderr, "No Name found in invitation!\n");
+ logger(mesh, MESHLINK_DEBUG, "No Name found in invitation!\n");
return false;
}
if(!check_id(name)) {
- fprintf(stderr, "Invalid Name found in invitation: %s!\n", name);
+ logger(mesh, MESHLINK_DEBUG, "Invalid Name found in invitation: %s!\n", name);
return false;
}
FILE *f = fopen(filename, "w");
if(!f) {
- fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Could not create file %s: %s\n", filename, strerror(errno));
return false;
}
snprintf(filename, sizeof filename, "%s" SLASH "hosts" SLASH "%s", mesh->confbase, name);
FILE *fh = fopen(filename, "w");
if(!fh) {
- fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Could not create file %s: %s\n", filename, strerror(errno));
fclose(f);
return false;
}
// Ignore unknown and unsafe variables
if(!found) {
- fprintf(stderr, "Ignoring unknown variable '%s' in invitation.\n", l);
+ logger(mesh, MESHLINK_DEBUG, "Ignoring unknown variable '%s' in invitation.\n", l);
continue;
} else if(!(variables[i].type & VAR_SAFE)) {
- fprintf(stderr, "Ignoring unsafe variable '%s' in invitation.\n", l);
+ logger(mesh, MESHLINK_DEBUG, "Ignoring unsafe variable '%s' in invitation.\n", l);
continue;
}
while(l && !strcasecmp(l, "Name")) {
if(!check_id(value)) {
- fprintf(stderr, "Invalid Name found in invitation.\n");
+ logger(mesh, MESHLINK_DEBUG, "Invalid Name found in invitation.\n");
return false;
}
if(!strcmp(value, name)) {
- fprintf(stderr, "Secondary chunk would overwrite our own host config file.\n");
+ logger(mesh, MESHLINK_DEBUG, "Secondary chunk would overwrite our own host config file.\n");
return false;
}
f = fopen(filename, "w");
if(!f) {
- fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Could not create file %s: %s\n", filename, strerror(errno));
return false;
}
mesh->self->name = xstrdup(name);
mesh->self->connection->name = name;
- fprintf(stderr, "Configuration stored in: %s\n", mesh->confbase);
+ logger(mesh, MESHLINK_DEBUG, "Configuration stored in: %s\n", mesh->confbase);
load_all_nodes(mesh);
return finalize_join(mesh);
case 2:
- fprintf(stderr, "Invitation succesfully accepted.\n");
+ logger(mesh, MESHLINK_DEBUG, "Invitation succesfully accepted.\n");
shutdown(mesh->sock, SHUT_RDWR);
mesh->success = true;
break;
FILE *f;
char pubname[PATH_MAX], privname[PATH_MAX];
- fprintf(stderr, "Generating ECDSA keypair:\n");
+ logger(mesh, MESHLINK_DEBUG, "Generating ECDSA keypair:\n");
if(!(key = ecdsa_generate())) {
- fprintf(stderr, "Error during key generation!\n");
+ logger(mesh, MESHLINK_DEBUG, "Error during key generation!\n");
meshlink_errno = MESHLINK_EINTERNAL;
return false;
} else
- fprintf(stderr, "Done.\n");
+ logger(mesh, MESHLINK_DEBUG, "Done.\n");
snprintf(privname, sizeof privname, "%s" SLASH "ecdsa_key.priv", mesh->confbase);
f = fopen(privname, "w");
#endif
if(!ecdsa_write_pem_private_key(key, f)) {
- fprintf(stderr, "Error writing private key!\n");
+ logger(mesh, MESHLINK_DEBUG, "Error writing private key!\n");
ecdsa_free(key);
fclose(f);
meshlink_errno = MESHLINK_EINTERNAL;
static bool meshlink_setup(meshlink_handle_t *mesh) {
if(mkdir(mesh->confbase, 0777) && errno != EEXIST) {
- fprintf(stderr, "Could not create directory %s: %s\n", mesh->confbase, strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Could not create directory %s: %s\n", mesh->confbase, strerror(errno));
meshlink_errno = MESHLINK_ESTORAGE;
return false;
}
snprintf(filename, sizeof filename, "%s" SLASH "hosts", mesh->confbase);
if(mkdir(filename, 0777) && errno != EEXIST) {
- fprintf(stderr, "Could not create directory %s: %s\n", filename, strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Could not create directory %s: %s\n", filename, strerror(errno));
meshlink_errno = MESHLINK_ESTORAGE;
return false;
}
snprintf(filename, sizeof filename, "%s" SLASH "meshlink.conf", mesh->confbase);
if(!access(filename, F_OK)) {
- fprintf(stderr, "Configuration file %s already exists!\n", filename);
+ logger(mesh, MESHLINK_DEBUG, "Configuration file %s already exists!\n", filename);
meshlink_errno = MESHLINK_EEXIST;
return false;
}
FILE *f = fopen(filename, "w");
if(!f) {
- fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Could not create file %s: %s\n", filename, strerror(errno));
meshlink_errno = MESHLINK_ESTORAGE;
return false;
}
bool usingname = false;
if(!confbase || !*confbase) {
- fprintf(stderr, "No confbase given!\n");
+ logger(NULL, MESHLINK_ERROR, "No confbase given!\n");
meshlink_errno = MESHLINK_EINVAL;
return NULL;
}
if(!appname || !*appname) {
- fprintf(stderr, "No appname given!\n");
+ logger(NULL, MESHLINK_ERROR, "No appname given!\n");
meshlink_errno = MESHLINK_EINVAL;
return NULL;
}
if(!name || !*name) {
- fprintf(stderr, "No name given!\n");
+ logger(NULL, MESHLINK_ERROR, "No name given!\n");
//return NULL;
}
else { //check name only if there is a name != NULL
if(!check_id(name)) {
- fprintf(stderr, "Invalid name given!\n");
+ logger(NULL, MESHLINK_ERROR, "Invalid name given!\n");
meshlink_errno = MESHLINK_EINVAL;
return NULL;
} else { usingname = true;}
event_loop_init(&mesh->loop);
mesh->loop.data = mesh;
- // TODO: should be set by a function.
- mesh->debug_level = 5;
-
// Check whether meshlink.conf already exists
char filename[PATH_MAX];
return NULL;
}
} else {
- fprintf(stderr, "Cannot not read from %s: %s\n", filename, strerror(errno));
+ logger(NULL, MESHLINK_ERROR, "Cannot not read from %s: %s\n", filename, strerror(errno));
meshlink_close(mesh);
meshlink_errno = MESHLINK_ESTORAGE;
return NULL;
try_outgoing_connections(mesh);
- fprintf(stderr, "Starting main_loop...\n");
+ logger(mesh, MESHLINK_DEBUG, "Starting main_loop...\n");
main_loop(mesh);
- fprintf(stderr, "main_loop returned.\n");
+ logger(mesh, MESHLINK_DEBUG, "main_loop returned.\n");
return NULL;
}
bool meshlink_start(meshlink_handle_t *mesh) {
- fprintf(stderr, "meshlink_start called\n");
+ logger(mesh, MESHLINK_DEBUG, "meshlink_start called\n");
if(!mesh) {
meshlink_errno = MESHLINK_EINVAL;
//Check that a valid name is set
if(!mesh->name ) {
- fprintf(stderr, "No name given!\n");
+ logger(mesh, MESHLINK_DEBUG, "No name given!\n");
meshlink_errno = MESHLINK_EINVAL;
return false;
}
// Start the main thread
if(pthread_create(&mesh->thread, NULL, meshlink_main_loop, mesh) != 0) {
- fprintf(stderr, "Could not start thread: %s\n", strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Could not start thread: %s\n", strerror(errno));
memset(&mesh->thread, 0, sizeof mesh->thread);
meshlink_errno = MESHLINK_EINTERNAL;
return false;
void meshlink_stop(meshlink_handle_t *mesh) {
- fprintf(stderr, "meshlink_stop called\n");
+ logger(mesh, MESHLINK_DEBUG, "meshlink_stop called\n");
if(!mesh) {
meshlink_errno = MESHLINK_EINVAL;
io_del(&mesh->loop, &s->tcp);
s->tcp.fd = setup_listen_socket(&s->sa);
if(s->tcp.fd < 0)
- logger(DEBUG_ALWAYS, LOG_ERR, "Could not repair listenen socket!");
+ logger(mesh, MESHLINK_ERROR, "Could not repair listenen socket!");
else
io_add(&mesh->loop, &s->tcp, handle_new_meta_connection, s, s->tcp.fd, IO_READ);
}
close_network_connections(mesh);
- logger(DEBUG_ALWAYS, LOG_NOTICE, "Terminating");
+ logger(mesh, MESHLINK_INFO, "Terminating");
exit_configuration(&mesh->config);
event_loop_exit(&mesh->loop);
}
void meshlink_set_log_cb(meshlink_handle_t *mesh, meshlink_log_level_t level, meshlink_log_cb_t cb) {
- if(!mesh) {
- meshlink_errno = MESHLINK_EINVAL;
- return;
+ if(mesh) {
+ mesh->log_cb = cb;
+ mesh->log_level = cb ? level : 0;
+ } else {
+ global_log_cb = cb;
+ global_log_level = cb ? level : 0;
}
-
- mesh->log_cb = cb;
- mesh->log_level = level;
}
bool meshlink_send(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, size_t len) {
snprintf(filename, sizeof filename, "%s" SLASH "invitations", mesh->confbase);
if(mkdir(filename, 0700) && errno != EEXIST) {
- fprintf(stderr, "Could not create directory %s: %s\n", filename, strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Could not create directory %s: %s\n", filename, strerror(errno));
meshlink_errno = MESHLINK_ESTORAGE;
return false;
}
// Count the number of valid invitations, clean up old ones
DIR *dir = opendir(filename);
if(!dir) {
- fprintf(stderr, "Could not read directory %s: %s\n", filename, strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Could not read directory %s: %s\n", filename, strerror(errno));
meshlink_errno = MESHLINK_ESTORAGE;
return false;
}
else
unlink(invname);
} else {
- fprintf(stderr, "Could not stat %s: %s\n", invname, strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Could not stat %s: %s\n", invname, strerror(errno));
errno = 0;
}
}
if(errno) {
- fprintf(stderr, "Error while reading directory %s: %s\n", filename, strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Error while reading directory %s: %s\n", filename, strerror(errno));
closedir(dir);
meshlink_errno = MESHLINK_ESTORAGE;
return false;
FILE *f = fopen(filename, "r");
if(!f) {
if(errno != ENOENT) {
- fprintf(stderr, "Could not read %s: %s\n", filename, strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Could not read %s: %s\n", filename, strerror(errno));
meshlink_errno = MESHLINK_ESTORAGE;
return false;
}
mesh->invitation_key = ecdsa_generate();
if(!mesh->invitation_key) {
- fprintf(stderr, "Could not generate a new key!\n");
+ logger(mesh, MESHLINK_DEBUG, "Could not generate a new key!\n");
meshlink_errno = MESHLINK_EINTERNAL;
return false;
}
f = fopen(filename, "w");
if(!f) {
- fprintf(stderr, "Could not write %s: %s\n", filename, strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Could not write %s: %s\n", filename, strerror(errno));
meshlink_errno = MESHLINK_ESTORAGE;
return false;
}
mesh->invitation_key = ecdsa_read_pem_private_key(f);
fclose(f);
if(!mesh->invitation_key) {
- fprintf(stderr, "Could not read private key from %s\n", filename);
+ logger(mesh, MESHLINK_DEBUG, "Could not read private key from %s\n", filename);
meshlink_errno = MESHLINK_ESTORAGE;
}
}
for(const char *p = address; *p; p++) {
if(isalnum(*p) || *p == '-' || *p == '.' || *p == ':')
continue;
- fprintf(stderr, "Invalid character in address: %s\n", address);
+ logger(mesh, MESHLINK_DEBUG, "Invalid character in address: %s\n", address);
meshlink_errno = MESHLINK_EINVAL;
return false;
}
// Check validity of the new node's name
if(!check_id(name)) {
- fprintf(stderr, "Invalid name for node.\n");
+ logger(mesh, MESHLINK_DEBUG, "Invalid name for node.\n");
meshlink_errno = MESHLINK_EINVAL;
return NULL;
}
char filename[PATH_MAX];
snprintf(filename, sizeof filename, "%s" SLASH "hosts" SLASH "%s", mesh->confbase, name);
if(!access(filename, F_OK)) {
- fprintf(stderr, "A host config file for %s already exists!\n", name);
+ logger(mesh, MESHLINK_DEBUG, "A host config file for %s already exists!\n", name);
meshlink_errno = MESHLINK_EEXIST;
return NULL;
}
// Ensure no other nodes know about this name
if(meshlink_get_node(mesh, name)) {
- fprintf(stderr, "A node with name %s is already known!\n", name);
+ logger(mesh, MESHLINK_DEBUG, "A node with name %s is already known!\n", name);
meshlink_errno = MESHLINK_EEXIST;
return NULL;
}
// Get the local address
char *address = get_my_hostname(mesh);
if(!address) {
- fprintf(stderr, "No Address known for ourselves!\n");
+ logger(mesh, MESHLINK_DEBUG, "No Address known for ourselves!\n");
meshlink_errno = MESHLINK_ERESOLV;
return NULL;
}
snprintf(filename, sizeof filename, "%s" SLASH "invitations" SLASH "%s", mesh->confbase, cookiehash);
int ifd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
if(!ifd) {
- fprintf(stderr, "Could not create invitation file %s: %s\n", filename, strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Could not create invitation file %s: %s\n", filename, strerror(errno));
meshlink_errno = MESHLINK_ESTORAGE;
return NULL;
}
}
fclose(tc);
} else {
- fprintf(stderr, "Could not create %s: %s\n", filename, strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Could not create %s: %s\n", filename, strerror(errno));
meshlink_errno = MESHLINK_ESTORAGE;
return NULL;
}
mesh->sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if(mesh->sock <= 0) {
- fprintf(stderr, "Could not open socket: %s\n", strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Could not open socket: %s\n", strerror(errno));
freeaddrinfo(ai);
meshlink_errno = MESHLINK_ENETWORK;
return false;
}
if(connect(mesh->sock, ai->ai_addr, ai->ai_addrlen)) {
- fprintf(stderr, "Could not connect to %s port %s: %s\n", address, port, strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Could not connect to %s port %s: %s\n", address, port, strerror(errno));
closesocket(mesh->sock);
freeaddrinfo(ai);
meshlink_errno = MESHLINK_ENETWORK;
freeaddrinfo(ai);
- fprintf(stderr, "Connected to %s port %s...\n", address, port);
+ logger(mesh, MESHLINK_DEBUG, "Connected to %s port %s...\n", address, port);
// Tell him we have an invitation, and give him our throw-away key.
mesh->blen = 0;
if(!sendline(mesh->sock, "0 ?%s %d.%d", b64key, PROT_MAJOR, 1)) {
- fprintf(stderr, "Error sending request to %s port %s: %s\n", address, port, strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Error sending request to %s port %s: %s\n", address, port, strerror(errno));
closesocket(mesh->sock);
meshlink_errno = MESHLINK_ENETWORK;
return false;
int code, hismajor, hisminor = 0;
if(!recvline(mesh, sizeof mesh->line) || sscanf(mesh->line, "%d %s %d.%d", &code, hisname, &hismajor, &hisminor) < 3 || code != 0 || hismajor != PROT_MAJOR || !check_id(hisname) || !recvline(mesh, sizeof mesh->line) || !rstrip(mesh->line) || sscanf(mesh->line, "%d ", &code) != 1 || code != ACK || strlen(mesh->line) < 3) {
- fprintf(stderr, "Cannot read greeting from peer\n");
+ logger(mesh, MESHLINK_DEBUG, "Cannot read greeting from peer\n");
closesocket(mesh->sock);
meshlink_errno = MESHLINK_ENETWORK;
return false;
char *fingerprint = mesh->line + 2;
char hishash[64];
if(sha512(fingerprint, strlen(fingerprint), hishash)) {
- fprintf(stderr, "Could not create hash\n%s\n", mesh->line + 2);
+ logger(mesh, MESHLINK_DEBUG, "Could not create hash\n%s\n", mesh->line + 2);
meshlink_errno = MESHLINK_EINTERNAL;
return false;
}
if(memcmp(hishash, mesh->hash, 18)) {
- fprintf(stderr, "Peer has an invalid key!\n%s\n", mesh->line + 2);
+ logger(mesh, MESHLINK_DEBUG, "Peer has an invalid key!\n%s\n", mesh->line + 2);
meshlink_errno = MESHLINK_EPEER;
return false;
if(len < 0) {
if(errno == EINTR)
continue;
- fprintf(stderr, "Error reading data from %s port %s: %s\n", address, port, strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Error reading data from %s port %s: %s\n", address, port, strerror(errno));
meshlink_errno = MESHLINK_ENETWORK;
return false;
}
closesocket(mesh->sock);
if(!mesh->success) {
- fprintf(stderr, "Connection closed by peer, invitation cancelled.\n");
+ logger(mesh, MESHLINK_DEBUG, "Connection closed by peer, invitation cancelled.\n");
meshlink_errno = MESHLINK_EPEER;
return false;
}
return true;
invalid:
- fprintf(stderr, "Invalid invitation URL or you are already connected to a Mesh ?\n");
+ logger(mesh, MESHLINK_DEBUG, "Invalid invitation URL or you are already connected to a Mesh ?\n");
meshlink_errno = MESHLINK_EINVAL;
return false;
}
snprintf(filename, sizeof filename, "%s" SLASH "hosts" SLASH "%s", mesh->confbase, mesh->self->name);
FILE *f = fopen(filename, "r");
if(!f) {
- fprintf(stderr, "Could not open %s: %s\n", filename, strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Could not open %s: %s\n", filename, strerror(errno));
meshlink_errno = MESHLINK_ESTORAGE;
return NULL;
}
char *buf = xmalloc(len);
snprintf(buf, len, "Name = %s\n", mesh->self->name);
if(fread(buf + len - fsize - 1, fsize, 1, f) != 1) {
- fprintf(stderr, "Error reading from %s: %s\n", filename, strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Error reading from %s: %s\n", filename, strerror(errno));
fclose(f);
meshlink_errno = MESHLINK_ESTORAGE;
return NULL;
}
if(strncmp(data, "Name = ", 7)) {
- fprintf(stderr, "Invalid data\n");
+ logger(mesh, MESHLINK_DEBUG, "Invalid data\n");
meshlink_errno = MESHLINK_EPEER;
return false;
}
char *end = strchr(data + 7, '\n');
if(!end) {
- fprintf(stderr, "Invalid data\n");
+ logger(mesh, MESHLINK_DEBUG, "Invalid data\n");
meshlink_errno = MESHLINK_EPEER;
return false;
}
memcpy(name, data + 7, len);
name[len] = 0;
if(!check_id(name)) {
- fprintf(stderr, "Invalid Name\n");
+ logger(mesh, MESHLINK_DEBUG, "Invalid Name\n");
meshlink_errno = MESHLINK_EPEER;
return false;
}
char filename[PATH_MAX];
snprintf(filename, sizeof filename, "%s" SLASH "hosts" SLASH "%s", mesh->confbase, name);
if(!access(filename, F_OK)) {
- fprintf(stderr, "File %s already exists, not importing\n", filename);
+ logger(mesh, MESHLINK_DEBUG, "File %s already exists, not importing\n", filename);
meshlink_errno = MESHLINK_EEXIST;
return false;
}
if(errno != ENOENT) {
- fprintf(stderr, "Error accessing %s: %s\n", filename, strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Error accessing %s: %s\n", filename, strerror(errno));
meshlink_errno = MESHLINK_ESTORAGE;
return false;
}
FILE *f = fopen(filename, "w");
if(!f) {
- fprintf(stderr, "Could not create %s: %s\n", filename, strerror(errno));
+ logger(mesh, MESHLINK_DEBUG, "Could not create %s: %s\n", filename, strerror(errno));
meshlink_errno = MESHLINK_ESTORAGE;
return false;
}
node_t *n;
n = (node_t*)node;
n->status.blacklisted=true;
- fprintf(stderr, "Blacklisted %s.\n",node->name);
+ logger(mesh, MESHLINK_DEBUG, "Blacklisted %s.\n",node->name);
//Make blacklisting persistent in the config file
append_config_file(mesh, n->name, "blacklisted", "yes");
} meshlink_log_level_t;
/// A callback for receiving log messages generated by MeshLink.
-/** @param mesh A handle which represents an instance of MeshLink.
+/** @param mesh A handle which represents an instance of MeshLink, or NULL.
* @param level An enum describing the severity level of the message.
* @param text A pointer to a nul-terminated C string containing the textual log message.
* This pointer is only valid for the duration of the callback.
/// Set the log callback.
/** This functions sets the callback that is called whenever MeshLink has some information to log.
- * The callback is run in MeshLink's own thread.
+ *
+ * The @a mesh @a parameter can either be a valid MeshLink handle, or NULL.
+ * In case it is NULL, the callback will be called for errors that happen outside the context of a valid mesh instance.
+ * Otherwise, it will be called for errors that happen in the context of the given mesh instance.
+ *
+ * If @a mesh @a is not NULL, then the callback is run in MeshLink's own thread.
* It is important that the callback uses apprioriate methods (queues, pipes, locking, etc.)
* to hand the data over to the application's thread.
* The callback should also not block itself and return as quickly as possible.
*
- * @param mesh A handle which represents an instance of MeshLink.
+ * The @a mesh @a parameter can either be a valid MeshLink handle, or NULL.
+ * In case it is NULL, the callback will be called for errors that happen outside the context of a valid mesh instance.
+ * Otherwise, it will be called for errors that happen in the context of the given mesh instance.
+ *
+ * @param mesh A handle which represents an instance of MeshLink, or NULL.
* @param level An enum describing the minimum severity level. Debugging information with a lower level will not trigger the callback.
* @param cb A pointer to the function which will be called when another node sends data to the local node.
* If a NULL pointer is given, the callback will be disabled.
#include "event.h"
#include "hash.h"
-#include "logger.h"
#include "meshlink.h"
#include "meshlink_queue.h"
#include "sockaddr.h"
struct connection_t *everyone;
struct ecdsa *invitation_key;
- debug_t debug_level;
int pinginterval; /* seconds between pings */
int pingtimeout; /* seconds to wait for response */
int maxtimeout;
} __attribute__ ((__packed__)) meshlink_packethdr_t;
extern void meshlink_send_from_queue(event_loop_t* el,meshlink_handle_t *mesh);
+extern meshlink_log_level_t global_log_level;
+extern meshlink_log_cb_t global_log_cb;
#endif // MESHLINK_INTERNAL_H
meshlink_handle_t *mesh = c->mesh;
if(!c) {
- logger(DEBUG_ALWAYS, LOG_ERR, "send_meta_sptps() called with NULL pointer!");
+ logger(mesh, MESHLINK_ERROR, "send_meta_sptps() called with NULL pointer!");
abort();
}
bool send_meta(meshlink_handle_t *mesh, connection_t *c, const char *buffer, int length) {
if(!c) {
- logger(DEBUG_ALWAYS, LOG_ERR, "send_meta() called with NULL pointer!");
+ logger(mesh, MESHLINK_ERROR, "send_meta() called with NULL pointer!");
abort();
}
- logger(DEBUG_META, LOG_DEBUG, "Sending %d bytes of metadata to %s (%s)", length,
+ logger(mesh, MESHLINK_DEBUG, "Sending %d bytes of metadata to %s (%s)", length,
c->name, c->hostname);
if(c->allow_request == ID) {
char *request = (char *)data;
if(!c) {
- logger(DEBUG_ALWAYS, LOG_ERR, "receive_meta_sptps() called with NULL pointer!");
+ logger(mesh, MESHLINK_ERROR, "receive_meta_sptps() called with NULL pointer!");
abort();
}
buffer_compact(&c->inbuf, MAXBUFSIZE);
if(sizeof inbuf <= c->inbuf.len) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Input buffer full for %s (%s)", c->name, c->hostname);
+ logger(mesh, MESHLINK_ERROR, "Input buffer full for %s (%s)", c->name, c->hostname);
return false;
}
if(inlen <= 0) {
if(!inlen || !errno) {
- logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection closed by %s (%s)",
+ logger(mesh, MESHLINK_INFO, "Connection closed by %s (%s)",
c->name, c->hostname);
} else if(sockwouldblock(sockerrno))
return true;
else
- logger(DEBUG_ALWAYS, LOG_ERR, "Metadata socket read error for %s (%s): %s",
+ logger(mesh, MESHLINK_ERROR, "Metadata socket read error for %s (%s): %s",
c->name, c->hostname, sockstrerror(sockerrno));
return false;
}
- Check if we need to retry making an outgoing connection
*/
void terminate_connection(meshlink_handle_t *mesh, connection_t *c, bool report) {
- logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Closing connection with %s (%s)", c->name, c->hostname);
+ logger(mesh, MESHLINK_INFO, "Closing connection with %s (%s)", c->name, c->hostname);
c->status.active = false;
if(c->last_ping_time + mesh->pingtimeout <= mesh->loop.now.tv_sec) {
if(c->status.active) {
if(c->status.pinged) {
- logger(DEBUG_CONNECTIONS, LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)mesh->loop.now.tv_sec - c->last_ping_time);
+ logger(mesh, MESHLINK_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)mesh->loop.now.tv_sec - c->last_ping_time);
} else if(c->last_ping_time + mesh->pinginterval <= mesh->loop.now.tv_sec) {
send_ping(mesh, c);
continue;
}
} else {
if(c->status.connecting)
- logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout while connecting to %s (%s)", c->name, c->hostname);
+ logger(mesh, MESHLINK_WARNING, "Timeout while connecting to %s (%s)", c->name, c->hostname);
else
- logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout from %s (%s) during authentication", c->name, c->hostname);
+ logger(mesh, MESHLINK_WARNING, "Timeout from %s (%s) during authentication", c->name, c->hostname);
}
terminate_connection(mesh, c, c->status.active);
}
if(!found) {
//TODO: if the node is blacklisted the connection will not happen, but
//the user will read this debug message "Autoconnecting to %s" that is misleading
- logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name);
+ logger(mesh, MESHLINK_INFO, "Autoconnecting to %s", n->name);
outgoing_t *outgoing = xzalloc(sizeof *outgoing);
outgoing->mesh = mesh;
outgoing->name = xstrdup(n->name);
*/
if(mesh->contradicting_del_edge > 100 && mesh->contradicting_add_edge > 100) {
- logger(DEBUG_ALWAYS, LOG_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", mesh->sleeptime);
+ logger(mesh, MESHLINK_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", mesh->sleeptime);
usleep(mesh->sleeptime * 1000000LL);
mesh->sleeptime *= 2;
if(mesh->sleeptime < 0)
if(!c->outgoing || !c->node || c->node->edge_tree->count < 2)
break;
- logger(DEBUG_CONNECTIONS, LOG_INFO, "Autodisconnecting from %s", c->name);
+ logger(mesh, MESHLINK_INFO, "Autodisconnecting from %s", c->name);
list_delete(mesh->outgoings, c->outgoing);
c->outgoing = NULL;
terminate_connection(mesh, c, c->status.active);
}
}
if(!found) {
- logger(DEBUG_CONNECTIONS, LOG_INFO, "Cancelled outgoing connection to %s", o->name);
+ logger(mesh, MESHLINK_INFO, "Cancelled outgoing connection to %s", o->name);
/* The node variable is leaked in from using the list_each macro.
The o variable could be used, but using node directly
is more efficient.
signal_add(&(mesh->loop),&(mesh->datafromapp), (signal_cb_t)meshlink_send_from_queue,mesh, mesh->datafromapp.signum);
if(!event_loop_run(&mesh->loop)) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Error while waiting for input: %s", strerror(errno));
+ logger(mesh, MESHLINK_ERROR, "Error while waiting for input: %s", strerror(errno));
return 1;
}
n->mtuprobes++;
if(!n->status.reachable || !n->status.validkey) {
- logger(DEBUG_TRAFFIC, LOG_INFO, "Trying to send MTU probe to unreachable or rekeying node %s (%s)", n->name, n->hostname);
+ logger(mesh, MESHLINK_INFO, "Trying to send MTU probe to unreachable or rekeying node %s (%s)", n->name, n->hostname);
n->mtuprobes = 0;
return;
}
goto end;
}
- logger(DEBUG_TRAFFIC, LOG_INFO, "%s (%s) did not respond to UDP ping, restarting PMTU discovery", n->name, n->hostname);
+ logger(mesh, MESHLINK_INFO, "%s (%s) did not respond to UDP ping, restarting PMTU discovery", n->name, n->hostname);
n->status.udp_confirmed = false;
n->mtuprobes = 1;
n->minmtu = 0;
}
if(n->mtuprobes >= 10 && n->mtuprobes < 32 && !n->minmtu) {
- logger(DEBUG_TRAFFIC, LOG_INFO, "No response to MTU probes from %s (%s)", n->name, n->hostname);
+ logger(mesh, MESHLINK_INFO, "No response to MTU probes from %s (%s)", n->name, n->hostname);
n->mtuprobes = 31;
}
else
n->maxmtu = n->minmtu;
n->mtu = n->minmtu;
- logger(DEBUG_TRAFFIC, LOG_INFO, "Fixing MTU of %s (%s) to %d after %d probes", n->name, n->hostname, n->mtu, n->mtuprobes);
+ logger(mesh, MESHLINK_INFO, "Fixing MTU of %s (%s) to %d after %d probes", n->name, n->hostname, n->mtu, n->mtuprobes);
n->mtuprobes = 31;
}
packet.len = len;
n->status.broadcast = i >= 4 && n->mtuprobes <= 10 && n->prevedge;
- logger(DEBUG_TRAFFIC, LOG_INFO, "Sending MTU probe length %d to %s (%s)", len, n->name, n->hostname);
+ logger(mesh, MESHLINK_INFO, "Sending MTU probe length %d to %s (%s)", len, n->name, n->hostname);
send_udppacket(mesh, n, &packet);
}
}
static void mtu_probe_h(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet, uint16_t len) {
- logger(DEBUG_TRAFFIC, LOG_INFO, "Got MTU probe length %d from %s (%s)", packet->len, n->name, n->hostname);
+ logger(mesh, MESHLINK_INFO, "Got MTU probe length %d from %s (%s)", packet->len, n->name, n->hostname);
if(!packet->data[0]) {
/* It's a probe request, send back a reply */
if(n->mtuprobes > 30) {
if (len == n->maxmtu + 8) {
- logger(DEBUG_TRAFFIC, LOG_INFO, "Increase in PMTU to %s (%s) detected, restarting PMTU discovery", n->name, n->hostname);
+ logger(mesh, MESHLINK_INFO, "Increase in PMTU to %s (%s) detected, restarting PMTU discovery", n->name, n->hostname);
n->maxmtu = MTU;
n->mtuprobes = 10;
return;
n->probe_time = now;
} else if(n->probe_counter == 3) {
n->bandwidth = 2.0 * len / (diff.tv_sec + diff.tv_usec * 1e-6);
- logger(DEBUG_TRAFFIC, LOG_DEBUG, "%s (%s) RTT %.2f ms, burst bandwidth %.3f Mbit/s, rx packet loss %.2f %%", n->name, n->hostname, n->rtt * 1e3, n->bandwidth * 8e-6, n->packetloss * 1e2);
+ logger(mesh, MESHLINK_DEBUG, "%s (%s) RTT %.2f ms, burst bandwidth %.3f Mbit/s, rx packet loss %.2f %%", n->name, n->hostname, n->rtt * 1e3, n->bandwidth * 8e-6, n->packetloss * 1e2);
}
}
}
/* VPN packet I/O */
static void receive_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
- logger(DEBUG_TRAFFIC, LOG_DEBUG, "Received packet of %d bytes from %s (%s)",
+ logger(mesh, MESHLINK_DEBUG, "Received packet of %d bytes from %s (%s)",
packet->len, n->name, n->hostname);
if (n->status.blacklisted) {
- logger(DEBUG_PROTOCOL, LOG_WARNING, "Dropping packet from blacklisted node %s", n->name);
+ logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
} else {
n->in_packets++;
n->in_bytes += packet->len;
static void receive_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *inpkt) {
if(!n->sptps.state) {
if(!n->status.waitingforkey) {
- logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but we haven't exchanged keys yet", n->name, n->hostname);
+ logger(mesh, MESHLINK_DEBUG, "Got packet from %s (%s) but we haven't exchanged keys yet", n->name, n->hostname);
send_req_key(mesh, n);
} else {
- logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname);
+ logger(mesh, MESHLINK_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname);
}
return;
}
static void send_sptps_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
if(!n->status.validkey) {
- logger(DEBUG_TRAFFIC, LOG_INFO, "No valid key known yet for %s (%s)", n->name, n->hostname);
+ logger(mesh, MESHLINK_INFO, "No valid key known yet for %s (%s)", n->name, n->hostname);
if(!n->status.waitingforkey)
send_req_key(mesh, n);
else if(n->last_req_key + 10 < mesh->loop.now.tv_sec) {
- logger(DEBUG_ALWAYS, LOG_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name);
+ logger(mesh, MESHLINK_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name);
sptps_stop(&n->sptps);
n->status.waitingforkey = false;
send_req_key(mesh, n);
if(n->outcompression) {
int len = compress_packet(outpkt.data, origpkt->data, origpkt->len, n->outcompression);
if(len < 0) {
- logger(DEBUG_TRAFFIC, LOG_ERR, "Error while compressing packet to %s (%s)", n->name, n->hostname);
+ logger(mesh, MESHLINK_ERROR, "Error while compressing packet to %s (%s)", n->name, n->hostname);
} else if(len < origpkt->len) {
outpkt.len = len;
origpkt = &outpkt;
static void send_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
if(!n->status.reachable) {
- logger(DEBUG_TRAFFIC, LOG_INFO, "Trying to send UDP packet to unreachable node %s (%s)", n->name, n->hostname);
+ logger(mesh, MESHLINK_INFO, "Trying to send UDP packet to unreachable node %s (%s)", n->name, n->hostname);
return;
}
if(to->mtu >= len)
to->mtu = len - 1;
} else {
- logger(DEBUG_TRAFFIC, LOG_WARNING, "Error sending UDP SPTPS packet to %s (%s): %s", to->name, to->hostname, sockstrerror(sockerrno));
+ logger(mesh, MESHLINK_WARNING, "Error sending UDP SPTPS packet to %s (%s): %s", to->name, to->hostname, sockstrerror(sockerrno));
return false;
}
}
if(!from->status.validkey) {
from->status.validkey = true;
from->status.waitingforkey = false;
- logger(DEBUG_META, LOG_INFO, "SPTPS key exchange with %s (%s) succesful", from->name, from->hostname);
+ logger(mesh, MESHLINK_INFO, "SPTPS key exchange with %s (%s) succesful", from->name, from->hostname);
}
return true;
}
if(len > MTU) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Packet from %s (%s) larger than maximum supported size (%d > %d)", from->name, from->hostname, len, MTU);
+ logger(mesh, MESHLINK_ERROR, "Packet from %s (%s) larger than maximum supported size (%d > %d)", from->name, from->hostname, len, MTU);
return false;
}
}
if(type & ~(PKT_COMPRESSED)) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Unexpected SPTPS record type %d len %d from %s (%s)", type, len, from->name, from->hostname);
+ logger(mesh, MESHLINK_ERROR, "Unexpected SPTPS record type %d len %d from %s (%s)", type, len, from->name, from->hostname);
return false;
}
return;
}
- logger(DEBUG_TRAFFIC, LOG_ERR, "Sending packet of %d bytes to %s (%s)",
+ logger(mesh, MESHLINK_ERROR, "Sending packet of %d bytes to %s (%s)",
packet->len, n->name, n->hostname);
if(!n->status.reachable) {
- logger(DEBUG_TRAFFIC, LOG_INFO, "Node %s (%s) is not reachable",
+ logger(mesh, MESHLINK_INFO, "Node %s (%s) is not reachable",
n->name, n->hostname);
return;
}
if(from != mesh->self)
send_packet(mesh, mesh->self, packet);
- logger(DEBUG_TRAFFIC, LOG_INFO, "Broadcasting packet of %d bytes from %s (%s)",
+ logger(mesh, MESHLINK_INFO, "Broadcasting packet of %d bytes from %s (%s)",
packet->len, from->name, from->hostname);
for list_each(connection_t, c, mesh->connections)
if(len <= 0 || len > MAXSIZE) {
if(!sockwouldblock(sockerrno))
- logger(DEBUG_ALWAYS, LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno));
+ logger(mesh, MESHLINK_ERROR, "Receiving packet failed: %s", sockstrerror(sockerrno));
return;
}
n = try_harder(mesh, &from, &pkt);
if(n)
update_node_udp(mesh, n, &from);
- else if(mesh->debug_level >= DEBUG_PROTOCOL) {
+ else if(mesh->log_level >= MESHLINK_WARNING) {
hostname = sockaddr2hostname(&from);
- logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from unknown source %s", hostname);
+ logger(mesh, MESHLINK_WARNING, "Received UDP packet from unknown source %s", hostname);
free(hostname);
return;
}
}
if (n->status.blacklisted) {
- logger(DEBUG_PROTOCOL, LOG_WARNING, "Dropping packet from blacklisted node %s", n->name);
+ logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
return;
}
n->sock = ls - mesh->listen_socket;
fp = fopen(filename, "r");
if(!fp) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Error reading ECDSA private key file: %s", strerror(errno));
+ logger(mesh, MESHLINK_ERROR, "Error reading ECDSA private key file: %s", strerror(errno));
return false;
}
fclose(fp);
if(!mesh->self->connection->ecdsa)
- logger(DEBUG_ALWAYS, LOG_ERR, "Reading ECDSA private key file failed: %s", strerror(errno));
+ logger(mesh, MESHLINK_ERROR, "Reading ECDSA private key file failed: %s", strerror(errno));
return mesh->self->connection->ecdsa;
}
mesh->invitation_key = ecdsa_read_pem_private_key(fp);
fclose(fp);
if(!mesh->invitation_key)
- logger(DEBUG_ALWAYS, LOG_ERR, "Reading ECDSA private key file `%s' failed: %s", filename, strerror(errno));
+ logger(mesh, MESHLINK_ERROR, "Reading ECDSA private key file `%s' failed: %s", filename, strerror(errno));
}
return mesh->invitation_key;
snprintf(dname,PATH_MAX, "%s" SLASH "hosts", mesh->confbase);
dir = opendir(dname);
if(!dir) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", dname, strerror(errno));
+ logger(mesh, MESHLINK_ERROR, "Could not open %s: %s", dname, strerror(errno));
return;
}
return NULL;
if(!check_id(name)) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Invalid name for mesh->self!");
+ logger(mesh, MESHLINK_ERROR, "Invalid name for mesh->self!");
free(name);
return NULL;
}
free(address);
if(err || !ai) {
- logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "getaddrinfo", err == EAI_SYSTEM ? strerror(err) : gai_strerror(err));
+ logger(mesh, MESHLINK_ERROR, "System call `%s' failed: %s", "getaddrinfo", err == EAI_SYSTEM ? strerror(err) : gai_strerror(err));
return false;
}
continue;
if(mesh->listen_sockets >= MAXSOCKETS) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Too many listening sockets");
+ logger(mesh, MESHLINK_ERROR, "Too many listening sockets");
return false;
}
io_add(&mesh->loop, &mesh->listen_socket[mesh->listen_sockets].tcp, handle_new_meta_connection, &mesh->listen_socket[mesh->listen_sockets], tcp_fd, IO_READ);
io_add(&mesh->loop, &mesh->listen_socket[mesh->listen_sockets].udp, handle_incoming_vpn_data, &mesh->listen_socket[mesh->listen_sockets], udp_fd, IO_READ);
- if(mesh->debug_level >= DEBUG_CONNECTIONS) {
+ if(mesh->log_level >= MESHLINK_INFO) {
char *hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr);
- logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Listening on %s", hostname);
+ logger(mesh, MESHLINK_INFO, "Listening on %s", hostname);
free(hostname);
}
char *address = NULL;
if(!(name = get_name(mesh))) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Name for MeshLink instance required!");
+ logger(mesh, MESHLINK_ERROR, "Name for MeshLink instance required!");
return false;
}
read_host_config(mesh, mesh->config, name);
if(!get_config_string(lookup_config(mesh->config, "Port"), &mesh->myport)) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Port for MeshLink instance required!");
+ logger(mesh, MESHLINK_ERROR, "Port for MeshLink instance required!");
return false;
}
return false;
if(!mesh->listen_sockets) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Unable to create any listening socket!");
+ logger(mesh, MESHLINK_ERROR, "Unable to create any listening socket!");
return false;
}
int flags = fcntl(c->socket, F_GETFL);
if(fcntl(c->socket, F_SETFL, flags | O_NONBLOCK) < 0) {
- logger(DEBUG_ALWAYS, LOG_ERR, "fcntl for %s: %s", c->hostname, strerror(errno));
+ logger(c->mesh, MESHLINK_ERROR, "fcntl for %s: %s", c->hostname, strerror(errno));
}
#elif defined(WIN32)
unsigned long arg = 1;
if(ioctlsocket(c->socket, FIONBIO, &arg) != 0) {
- logger(DEBUG_ALWAYS, LOG_ERR, "ioctlsocket for %s: %s", c->hostname, sockstrerror(sockerrno));
+ logger(c->mesh, MESHLINK_ERROR, "ioctlsocket for %s: %s", c->hostname, sockstrerror(sockerrno));
}
#endif
sa.in6.sin6_port = 0;
if(bind(c->socket, &sa.sa, SALEN(sa.sa))) {
- logger(DEBUG_CONNECTIONS, LOG_WARNING, "Can't bind outgoing socket: %s", strerror(errno));
+ logger(mesh, MESHLINK_WARNING, "Can't bind outgoing socket: %s", strerror(errno));
return false;
}
nfd = socket(sa->sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
if(nfd < 0) {
- logger(DEBUG_STATUS, LOG_ERR, "Creating metasocket failed: %s", sockstrerror(sockerrno));
+ logger(NULL, MESHLINK_ERROR, "Creating metasocket failed: %s", sockstrerror(sockerrno));
return -1;
}
if(bind(nfd, &sa->sa, SALEN(sa->sa))) {
closesocket(nfd);
addrstr = sockaddr2hostname(sa);
- logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to %s/tcp: %s", addrstr, sockstrerror(sockerrno));
+ logger(NULL, MESHLINK_ERROR, "Can't bind to %s/tcp: %s", addrstr, sockstrerror(sockerrno));
free(addrstr);
return -1;
}
if(listen(nfd, 3)) {
closesocket(nfd);
- logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "listen", sockstrerror(sockerrno));
+ logger(NULL, MESHLINK_ERROR, "System call `%s' failed: %s", "listen", sockstrerror(sockerrno));
return -1;
}
nfd = socket(sa->sa.sa_family, SOCK_DGRAM, IPPROTO_UDP);
if(nfd < 0) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Creating UDP socket failed: %s", sockstrerror(sockerrno));
+ logger(mesh, MESHLINK_ERROR, "Creating UDP socket failed: %s", sockstrerror(sockerrno));
return -1;
}
if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
closesocket(nfd);
- logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "fcntl",
+ logger(mesh, MESHLINK_ERROR, "System call `%s' failed: %s", "fcntl",
strerror(errno));
return -1;
}
unsigned long arg = 1;
if(ioctlsocket(nfd, FIONBIO, &arg) != 0) {
closesocket(nfd);
- logger(DEBUG_ALWAYS, LOG_ERR, "Call to `%s' failed: %s", "ioctlsocket", sockstrerror(sockerrno));
+ logger(mesh, MESHLINK_ERROR, "Call to `%s' failed: %s", "ioctlsocket", sockstrerror(sockerrno));
return -1;
}
}
if(bind(nfd, &sa->sa, SALEN(sa->sa))) {
closesocket(nfd);
addrstr = sockaddr2hostname(sa);
- logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to %s/udp: %s", addrstr, sockstrerror(sockerrno));
+ logger(mesh, MESHLINK_ERROR, "Can't bind to %s/udp: %s", addrstr, sockstrerror(sockerrno));
free(addrstr);
return -1;
}
timeout_add(&mesh->loop, &outgoing->ev, retry_outgoing_handler, outgoing, &(struct timeval){outgoing->timeout, rand() % 100000});
- logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Trying to re-establish outgoing connection in %d seconds", outgoing->timeout);
+ logger(mesh, MESHLINK_INFO, "Trying to re-establish outgoing connection in %d seconds", outgoing->timeout);
}
void finish_connecting(meshlink_handle_t *mesh, connection_t *c) {
- logger(DEBUG_CONNECTIONS, LOG_INFO, "Connected to %s (%s)", c->name, c->hostname);
+ logger(mesh, MESHLINK_INFO, "Connected to %s (%s)", c->name, c->hostname);
c->last_ping_time = mesh->loop.now.tv_sec;
c->status.connecting = false;
int fd[2];
if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Could not create socketpair: %s", strerror(errno));
+ logger(mesh, MESHLINK_ERROR, "Could not create socketpair: %s", strerror(errno));
return;
}
if(fork()) {
c->socket = fd[0];
close(fd[1]);
- logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Using proxy %s", command);
+ logger(mesh, MESHLINK_DEBUG, "Using proxy %s", command);
return;
}
int result = system(command);
if(result < 0)
- logger(DEBUG_ALWAYS, LOG_ERR, "Could not execute %s: %s", command, strerror(errno));
+ logger(mesh, MESHLINK_ERROR, "Could not execute %s: %s", command, strerror(errno));
else if(result)
- logger(DEBUG_ALWAYS, LOG_ERR, "%s exited with non-zero status %d", command, result);
+ logger(mesh, MESHLINK_ERROR, "%s exited with non-zero status %d", command, result);
exit(result);
#else
- logger(DEBUG_ALWAYS, LOG_ERR, "Proxy type exec not supported on this platform!");
+ logger(mesh, MESHLINK_ERROR, "Proxy type exec not supported on this platform!");
return;
#endif
}
ssize_t outlen = send(c->socket, c->outbuf.data + c->outbuf.offset, c->outbuf.len - c->outbuf.offset, MSG_NOSIGNAL);
if(outlen <= 0) {
if(!errno || errno == EPIPE) {
- logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection closed by %s (%s)", c->name, c->hostname);
+ logger(mesh, MESHLINK_INFO, "Connection closed by %s (%s)", c->name, c->hostname);
} else if(sockwouldblock(sockerrno)) {
- logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Sending %d bytes to %s (%s) would block", c->outbuf.len - c->outbuf.offset, c->name, c->hostname);
+ logger(mesh, MESHLINK_DEBUG, "Sending %d bytes to %s (%s) would block", c->outbuf.len - c->outbuf.offset, c->name, c->hostname);
return;
} else {
- logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not send %d bytes of data to %s (%s): %s", c->outbuf.len - c->outbuf.offset, c->name, c->hostname, strerror(errno));
+ logger(mesh, MESHLINK_ERROR, "Could not send %d bytes of data to %s (%s): %s", c->outbuf.len - c->outbuf.offset, c->name, c->hostname, strerror(errno));
}
terminate_connection(mesh, c, c->status.active);
if(!result)
finish_connecting(mesh, c);
else {
- logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Error while connecting to %s (%s): %s", c->name, c->hostname, sockstrerror(result));
+ logger(mesh, MESHLINK_DEBUG, "Error while connecting to %s (%s): %s", c->name, c->hostname, sockstrerror(result));
terminate_connection(mesh, c, false);
return;
}
begin:
if(!outgoing->ai) {
if(!outgoing->cfg) {
- logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not set up a meta connection to %s", outgoing->name);
+ logger(mesh, MESHLINK_ERROR, "Could not set up a meta connection to %s", outgoing->name);
retry_outgoing(mesh, outgoing);
return false;
}
} else {
// TODO: Only allow Address statements?
if(!get_config_string(lookup_config(outgoing->config_tree, "Port"), &port)) {
- logger(DEBUG_CONNECTIONS, LOG_ERR, "No Port known for %s", outgoing->name);
+ logger(mesh, MESHLINK_ERROR, "No Port known for %s", outgoing->name);
retry_outgoing(mesh, outgoing);
return false;
}
c->hostname = sockaddr2hostname(&c->address);
- logger(DEBUG_CONNECTIONS, LOG_INFO, "Trying to connect to %s (%s)", outgoing->name, c->hostname);
+ logger(mesh, MESHLINK_INFO, "Trying to connect to %s (%s)", outgoing->name, c->hostname);
if(!mesh->proxytype) {
c->socket = socket(c->address.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
free_connection(c);
goto begin;
}
- logger(DEBUG_CONNECTIONS, LOG_INFO, "Using proxy at %s port %s", mesh->proxyhost, mesh->proxyport);
+ logger(mesh, MESHLINK_INFO, "Using proxy at %s port %s", mesh->proxyhost, mesh->proxyport);
c->socket = socket(proxyai->ai_family, SOCK_STREAM, IPPROTO_TCP);
configure_tcp(c);
}
if(c->socket == -1) {
- logger(DEBUG_CONNECTIONS, LOG_ERR, "Creating socket for %s failed: %s", c->hostname, sockstrerror(sockerrno));
+ logger(mesh, MESHLINK_ERROR, "Creating socket for %s failed: %s", c->hostname, sockstrerror(sockerrno));
free_connection(c);
goto begin;
}
}
if(result == -1 && !sockinprogress(sockerrno)) {
- logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not connect to %s (%s): %s", outgoing->name, c->hostname, sockstrerror(sockerrno));
+ logger(mesh, MESHLINK_ERROR, "Could not connect to %s (%s): %s", outgoing->name, c->hostname, sockstrerror(sockerrno));
free_connection(c);
goto begin;
node_t *n = lookup_node(mesh, outgoing->name);
if(n && n->connection) {
- logger(DEBUG_CONNECTIONS, LOG_INFO, "Already connected to %s", outgoing->name);
+ logger(mesh, MESHLINK_INFO, "Already connected to %s", outgoing->name);
n->connection->outgoing = outgoing;
return;
if(n)
outgoing->aip = outgoing->ai = get_known_addresses(n);
if(!outgoing->ai) {
- logger(DEBUG_ALWAYS, LOG_ERR, "No address known for %s", outgoing->name);
+ logger(mesh, MESHLINK_ERROR, "No address known for %s", outgoing->name);
return;
}
}
return;
}
- logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno));
+ logger(mesh, MESHLINK_ERROR, "Accepting a new connection failed: %s", sockstrerror(sockerrno));
return;
}
c->socket = fd;
c->last_ping_time = mesh->loop.now.tv_sec;
- logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname);
+ logger(mesh, MESHLINK_INFO, "Connection from %s", c->hostname);
io_add(&mesh->loop, &c->io, handle_meta_io, c, c->socket, IO_READ);
get_config_string(cfg, &name);
if(!check_id(name)) {
- logger(DEBUG_ALWAYS, LOG_ERR,
+ logger(mesh, MESHLINK_ERROR,
"Invalid name for outgoing connection in %s line %d",
cfg->file, cfg->line);
free(name);
for list_each(connection_t, c, mesh->connections) {
if(c->outgoing && c->outgoing->timeout == -1) {
c->outgoing = NULL;
- logger(DEBUG_CONNECTIONS, LOG_INFO, "No more outgoing connection to %s", c->name);
+ logger(mesh, MESHLINK_INFO, "No more outgoing connection to %s", c->name);
terminate_connection(mesh, c, c->status.active);
}
}
err = getaddrinfo(address, service, &hint, &ai);
if(err) {
- logger(DEBUG_ALWAYS, LOG_WARNING, "Error looking up %s port %s: %s", address, service, err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err));
+ logger(NULL, MESHLINK_WARNING, "Error looking up %s port %s: %s", address, service, err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err));
return NULL;
}
err = getaddrinfo(address, port, &hint, &ai);
if(err || !ai) {
- logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Unknown type address %s port %s", address, port);
+ logger(NULL, MESHLINK_DEBUG, "Unknown type address %s port %s", address, port);
result.sa.sa_family = AF_UNKNOWN;
result.unknown.address = xstrdup(address);
result.unknown.port = xstrdup(port);
err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof address, port, sizeof port, NI_NUMERICHOST | NI_NUMERICSERV);
if(err) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Error while translating addresses: %s", err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err));
+ logger(NULL, MESHLINK_ERROR, "Error while translating addresses: %s", err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err));
abort();
}
err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof address, port, sizeof port,
hostnames ? 0 : (NI_NUMERICHOST | NI_NUMERICSERV));
if(err) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Error while looking up hostname: %s", err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err));
+ logger(NULL, MESHLINK_ERROR, "Error while looking up hostname: %s", err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err));
}
xasprintf(&str, "%s port %s", address, port);
return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr));
default:
- logger(DEBUG_ALWAYS, LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!",
+ logger(NULL, MESHLINK_ERROR, "sockaddrcmp() was called with unknown address family %d, exitting!",
a->sa.sa_family);
abort();
}
return memcmp(&a->in6.sin6_port, &b->in6.sin6_port, sizeof a->in6.sin6_port);
default:
- logger(DEBUG_ALWAYS, LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!",
+ logger(NULL, MESHLINK_ERROR, "sockaddrcmp() was called with unknown address family %d, exitting!",
a->sa.sa_family);
abort();
}
void update_node_udp(meshlink_handle_t *mesh, node_t *n, const sockaddr_t *sa) {
if(n == mesh->self) {
- logger(DEBUG_ALWAYS, LOG_WARNING, "Trying to update UDP address of mesh->self!");
+ logger(mesh, MESHLINK_WARNING, "Trying to update UDP address of mesh->self!");
return;
}
hash_insert(mesh->node_udp_cache, sa, n);
free(n->hostname);
n->hostname = sockaddr2hostname(&n->address);
- logger(DEBUG_PROTOCOL, LOG_DEBUG, "UDP address of %s set to %s", n->name, n->hostname);
+ logger(mesh, MESHLINK_DEBUG, "UDP address of %s set to %s", n->name, n->hostname);
}
}
va_end(args);
if(len < 0 || len > MAXBUFSIZE - 1) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Output buffer overflow while sending request to %s (%s)",
+ logger(mesh, MESHLINK_ERROR, "Output buffer overflow while sending request to %s (%s)",
c->name, c->hostname);
return false;
}
- logger(DEBUG_META, LOG_DEBUG, "Sending %s to %s (%s): %s", request_name[atoi(request)], c->name, c->hostname, request);
+ logger(mesh, MESHLINK_DEBUG, "Sending %s to %s (%s): %s", request_name[atoi(request)], c->name, c->hostname, request);
request[len++] = '\n';
}
void forward_request(meshlink_handle_t *mesh, connection_t *from, const char *request) {
- logger(DEBUG_META, LOG_DEBUG, "Forwarding %s from %s (%s): %s", request_name[atoi(request)], from->name, from->hostname, request);
+ logger(mesh, MESHLINK_DEBUG, "Forwarding %s from %s (%s): %s", request_name[atoi(request)], from->name, from->hostname, request);
// Create a temporary newline-terminated copy of the request
int len = strlen(request);
return true;
if(!strncasecmp(request, "HTTP/1.1 ", 9)) {
if(!strncmp(request + 9, "200", 3)) {
- logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Proxy request granted");
+ logger(mesh, MESHLINK_DEBUG, "Proxy request granted");
return true;
} else {
- logger(DEBUG_ALWAYS, LOG_DEBUG, "Proxy request rejected: %s", request + 9);
+ logger(mesh, MESHLINK_DEBUG, "Proxy request rejected: %s", request + 9);
return false;
}
}
if(reqno || *request == '0') {
if((reqno < 0) || (reqno >= LAST) || !request_handlers[reqno]) {
- logger(DEBUG_META, LOG_DEBUG, "Unknown request from %s (%s): %s", c->name, c->hostname, request);
+ logger(mesh, MESHLINK_DEBUG, "Unknown request from %s (%s): %s", c->name, c->hostname, request);
return false;
} else {
- logger(DEBUG_META, LOG_DEBUG, "Got %s from %s (%s): %s", request_name[reqno], c->name, c->hostname, request);
+ logger(mesh, MESHLINK_DEBUG, "Got %s from %s (%s): %s", request_name[reqno], c->name, c->hostname, request);
}
if((c->allow_request != ALL) && (c->allow_request != reqno)) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Unauthorized request from %s (%s)", c->name, c->hostname);
+ logger(mesh, MESHLINK_ERROR, "Unauthorized request from %s (%s)", c->name, c->hostname);
return false;
}
if(!request_handlers[reqno](mesh, c, request)) {
/* Something went wrong. Probably scriptkiddies. Terminate. */
- logger(DEBUG_ALWAYS, LOG_ERR, "Error while processing %s from %s (%s)", request_name[reqno], c->name, c->hostname);
+ logger(mesh, MESHLINK_ERROR, "Error while processing %s from %s (%s)", request_name[reqno], c->name, c->hostname);
return false;
}
} else {
- logger(DEBUG_ALWAYS, LOG_ERR, "Bogus data received from %s (%s)", c->name, c->hostname);
+ logger(mesh, MESHLINK_ERROR, "Bogus data received from %s (%s)", c->name, c->hostname);
return false;
}
}
if(left || deleted)
- logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Aging past requests: deleted %d, left %d", deleted, left);
+ logger(mesh, MESHLINK_DEBUG, "Aging past requests: deleted %d, left %d", deleted, left);
if(left)
timeout_set(&mesh->loop, &mesh->past_request_timeout, &(struct timeval){10, rand() % 100000});
p.request = request;
if(splay_search(mesh->past_request_tree, &p)) {
- logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Already seen request");
+ logger(mesh, MESHLINK_DEBUG, "Already seen request");
return true;
} else {
new = xmalloc(sizeof *new);
}
case PROXY_SOCKS4: {
if(c->address.sa.sa_family != AF_INET) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Cannot connect to an IPv6 host through a SOCKS 4 proxy!");
+ logger(mesh, MESHLINK_ERROR, "Cannot connect to an IPv6 host through a SOCKS 4 proxy!");
return false;
}
char s4req[9 + (mesh->proxyuser ? strlen(mesh->proxyuser) : 0)];
i += 2;
c->tcplen += 22;
} else {
- logger(DEBUG_ALWAYS, LOG_ERR, "Address family %hx not supported for SOCKS 5 proxies!", c->address.sa.sa_family);
+ logger(mesh, MESHLINK_ERROR, "Address family %hx not supported for SOCKS 5 proxies!", c->address.sa.sa_family);
return false;
}
if(i > len)
return send_meta(mesh, c, s5req, sizeof s5req);
}
case PROXY_SOCKS4A:
- logger(DEBUG_ALWAYS, LOG_ERR, "Proxy type not implemented yet");
+ logger(mesh, MESHLINK_ERROR, "Proxy type not implemented yet");
return false;
case PROXY_EXEC:
return true;
default:
- logger(DEBUG_ALWAYS, LOG_ERR, "Unknown proxy type");
+ logger(mesh, MESHLINK_ERROR, "Unknown proxy type");
return false;
}
}
static bool finalize_invitation(meshlink_handle_t *mesh, connection_t *c, const void *data, uint16_t len) {
if(strchr(data, '\n')) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Received invalid key from invited node %s (%s)!\n", c->name, c->hostname);
+ logger(mesh, MESHLINK_ERROR, "Received invalid key from invited node %s (%s)!\n", c->name, c->hostname);
return false;
}
char filename[PATH_MAX];
snprintf(filename, sizeof filename, "%s" SLASH "hosts" SLASH "%s", mesh->confbase, c->name);
if(!access(filename, F_OK)) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Host config file for %s (%s) already exists!\n", c->name, c->hostname);
+ logger(mesh, MESHLINK_ERROR, "Host config file for %s (%s) already exists!\n", c->name, c->hostname);
return false;
}
FILE *f = fopen(filename, "w");
if(!f) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Error trying to create %s: %s\n", filename, strerror(errno));
+ logger(mesh, MESHLINK_ERROR, "Error trying to create %s: %s\n", filename, strerror(errno));
return false;
}
fprintf(f, "ECDSAPublicKey = %s\n", (const char *)data);
fclose(f);
- logger(DEBUG_CONNECTIONS, LOG_INFO, "Key succesfully received from %s (%s)", c->name, c->hostname);
+ logger(mesh, MESHLINK_INFO, "Key succesfully received from %s (%s)", c->name, c->hostname);
//TODO: callback to application to inform of an accepted invitation
// Atomically rename the invitation file
if(rename(filename, usedname)) {
if(errno == ENOENT)
- logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s tried to use non-existing invitation %s\n", c->hostname, cookie);
+ logger(mesh, MESHLINK_ERROR, "Peer %s tried to use non-existing invitation %s\n", c->hostname, cookie);
else
- logger(DEBUG_ALWAYS, LOG_ERR, "Error trying to rename invitation %s\n", cookie);
+ logger(mesh, MESHLINK_ERROR, "Error trying to rename invitation %s\n", cookie);
return false;
}
// Open the renamed file
FILE *f = fopen(usedname, "r");
if(!f) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Error trying to open invitation %s\n", cookie);
+ logger(mesh, MESHLINK_ERROR, "Error trying to open invitation %s\n", cookie);
return false;
}
buf[len] = 0;
if(!*buf || !*name || strcasecmp(buf, "Name") || !check_id(name)) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Invalid invitation file %s\n", cookie);
+ logger(mesh, MESHLINK_ERROR, "Invalid invitation file %s\n", cookie);
fclose(f);
return false;
}
c->status.invitation_used = true;
- logger(DEBUG_CONNECTIONS, LOG_INFO, "Invitation %s succesfully sent to %s (%s)", cookie, c->name, c->hostname);
+ logger(mesh, MESHLINK_INFO, "Invitation %s succesfully sent to %s (%s)", cookie, c->name, c->hostname);
return true;
}
char name[MAX_STRING_SIZE];
if(sscanf(request, "%*d " MAX_STRING " %d.%d", name, &c->protocol_major, &c->protocol_minor) < 2) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ID", c->name,
+ logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s)", "ID", c->name,
c->hostname);
return false;
}
if(name[0] == '?') {
if(!mesh->invitation_key) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got invitation from %s but we don't have an invitation key", c->hostname);
+ logger(mesh, MESHLINK_ERROR, "Got invitation from %s but we don't have an invitation key", c->hostname);
return false;
}
c->ecdsa = ecdsa_set_base64_public_key(name + 1);
if(!c->ecdsa) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got bad invitation from %s", c->hostname);
+ logger(mesh, MESHLINK_ERROR, "Got bad invitation from %s", c->hostname);
return false;
}
/* Check if identity is a valid name */
if(!check_id(name)) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ID", c->name,
+ logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s): %s", "ID", c->name,
c->hostname, "invalid name");
return false;
}
if(c->outgoing) {
if(strcmp(c->name, name)) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s is %s instead of %s", c->hostname, name,
+ logger(mesh, MESHLINK_ERROR, "Peer %s is %s instead of %s", c->hostname, name,
c->name);
return false;
}
/* Check if version matches */
if(c->protocol_major != mesh->self->connection->protocol_major) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s (%s) uses incompatible version %d.%d",
+ logger(mesh, MESHLINK_ERROR, "Peer %s (%s) uses incompatible version %d.%d",
c->name, c->hostname, c->protocol_major, c->protocol_minor);
return false;
}
init_configuration(&c->config_tree);
if(!read_host_config(mesh, c->config_tree, c->name)) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s had unknown identity (%s)", c->hostname, c->name);
+ logger(mesh, MESHLINK_ERROR, "Peer %s had unknown identity (%s)", c->hostname, c->name);
return false;
}
/* Forbid version rollback for nodes whose ECDSA key we know */
if(ecdsa_active(c->ecdsa) && c->protocol_minor < 2) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s (%s) tries to roll back protocol version to %d.%d",
+ logger(mesh, MESHLINK_ERROR, "Peer %s (%s) tries to roll back protocol version to %d.%d",
c->name, c->hostname, c->protocol_major, c->protocol_minor);
return false;
}
node_t *n;
if(sscanf(request, "%*d " MAX_STRING " %d %x", hisport, &weight, &options) != 3) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ACK", c->name,
+ logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s)", "ACK", c->name,
c->hostname);
return false;
}
} else {
if(n->connection) {
/* Oh dear, we already have a connection to this node. */
- logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Established a second connection with %s (%s), closing old connection", n->connection->name, n->connection->hostname);
+ logger(mesh, MESHLINK_DEBUG, "Established a second connection with %s (%s), closing old connection", n->connection->name, n->connection->hostname);
if(n->connection->outgoing) {
if(c->outgoing)
- logger(DEBUG_ALWAYS, LOG_WARNING, "Two outgoing connections to the same node!");
+ logger(mesh, MESHLINK_WARNING, "Two outgoing connections to the same node!");
else
c->outgoing = n->connection->outgoing;
c->allow_request = ALL;
c->status.active = true;
- logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection with %s (%s) activated", c->name,
+ logger(mesh, MESHLINK_INFO, "Connection with %s (%s) activated", c->name,
c->hostname);
/* Send him everything we know */
if(sscanf(request, "%*d %*x "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %x %d",
from_name, to_name, to_address, to_port, &options, &weight) != 6) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ADD_EDGE", c->name,
+ logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s)", "ADD_EDGE", c->name,
c->hostname);
return false;
}
/* Check if names are valid */
if(!check_id(from_name) || !check_id(to_name)) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_EDGE", c->name,
+ logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s): %s", "ADD_EDGE", c->name,
c->hostname, "invalid name");
return false;
}
if(e) {
if(e->weight != weight || e->options != options || sockaddrcmp(&e->address, &address)) {
if(from == mesh->self) {
- logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry",
+ logger(mesh, MESHLINK_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry",
"ADD_EDGE", c->name, c->hostname);
send_add_edge(mesh, c, e);
return true;
} else {
- logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) which does not match existing entry",
+ logger(mesh, MESHLINK_WARNING, "Got %s from %s (%s) which does not match existing entry",
"ADD_EDGE", c->name, c->hostname);
edge_del(mesh, e);
graph(mesh);
} else
return true;
} else if(from == mesh->self) {
- logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not exist",
+ logger(mesh, MESHLINK_WARNING, "Got %s from %s (%s) for ourself which does not exist",
"ADD_EDGE", c->name, c->hostname);
mesh->contradicting_add_edge++;
e = new_edge();
node_t *from, *to;
if(sscanf(request, "%*d %*x "MAX_STRING" "MAX_STRING, from_name, to_name) != 2) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "DEL_EDGE", c->name,
+ logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s)", "DEL_EDGE", c->name,
c->hostname);
return false;
}
/* Check if names are valid */
if(!check_id(from_name) || !check_id(to_name)) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_EDGE", c->name,
+ logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s): %s", "DEL_EDGE", c->name,
c->hostname, "invalid name");
return false;
}
to = lookup_node(mesh, to_name);
if(!from) {
- logger(DEBUG_PROTOCOL, LOG_ERR, "Got %s from %s (%s) which does not appear in the edge tree",
+ logger(mesh, MESHLINK_ERROR, "Got %s from %s (%s) which does not appear in the edge tree",
"DEL_EDGE", c->name, c->hostname);
return true;
}
if(!to) {
- logger(DEBUG_PROTOCOL, LOG_ERR, "Got %s from %s (%s) which does not appear in the edge tree",
+ logger(mesh, MESHLINK_ERROR, "Got %s from %s (%s) which does not appear in the edge tree",
"DEL_EDGE", c->name, c->hostname);
return true;
}
e = lookup_edge(from, to);
if(!e) {
- logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) which does not appear in the edge tree",
+ logger(mesh, MESHLINK_WARNING, "Got %s from %s (%s) which does not appear in the edge tree",
"DEL_EDGE", c->name, c->hostname);
return true;
}
if(e->from == mesh->self) {
- logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself",
+ logger(mesh, MESHLINK_WARNING, "Got %s from %s (%s) for ourself",
"DEL_EDGE", c->name, c->hostname);
mesh->contradicting_del_edge++;
send_add_edge(mesh, c, e); /* Send back a correction */
node_t *n;
if(sscanf(request, "%*d %*x " MAX_STRING, name) != 1) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "KEY_CHANGED",
+ logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s)", "KEY_CHANGED",
c->name, c->hostname);
return false;
}
n = lookup_node(mesh, name);
if(!n) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist",
+ logger(mesh, MESHLINK_ERROR, "Got %s from %s (%s) origin %s which does not exist",
"KEY_CHANGED", c->name, c->hostname, name);
return true;
}
bool send_req_key(meshlink_handle_t *mesh, node_t *to) {
if(!node_read_ecdsa_public_key(mesh, to)) {
- logger(DEBUG_PROTOCOL, LOG_DEBUG, "No ECDSA key known for %s (%s)", to->name, to->hostname);
+ logger(mesh, MESHLINK_DEBUG, "No ECDSA key known for %s (%s)", to->name, to->hostname);
send_request(mesh, to->nexthop->connection, "%d %s %s %d", REQ_KEY, mesh->self->name, to->name, REQ_PUBKEY);
return true;
}
if(to->sptps.label)
- logger(DEBUG_ALWAYS, LOG_DEBUG, "send_req_key(%s) called while sptps->label != NULL!", to->name);
+ logger(mesh, MESHLINK_DEBUG, "send_req_key(%s) called while sptps->label != NULL!", to->name);
char label[25 + strlen(mesh->self->name) + strlen(to->name)];
snprintf(label, sizeof label, "MeshLink UDP key expansion %s %s", mesh->self->name, to->name);
case ANS_PUBKEY: {
if(node_read_ecdsa_public_key(mesh, from)) {
- logger(DEBUG_PROTOCOL, LOG_WARNING, "Got ANS_PUBKEY from %s (%s) even though we already have his pubkey", from->name, from->hostname);
+ logger(mesh, MESHLINK_WARNING, "Got ANS_PUBKEY from %s (%s) even though we already have his pubkey", from->name, from->hostname);
return true;
}
char pubkey[MAX_STRING_SIZE];
if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, pubkey) != 1 || !(from->ecdsa = ecdsa_set_base64_public_key(pubkey))) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_PUBKEY", from->name, from->hostname, "invalid pubkey");
+ logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s): %s", "ANS_PUBKEY", from->name, from->hostname, "invalid pubkey");
return true;
}
- logger(DEBUG_PROTOCOL, LOG_INFO, "Learned ECDSA public key from %s (%s)", from->name, from->hostname);
+ logger(mesh, MESHLINK_INFO, "Learned ECDSA public key from %s (%s)", from->name, from->hostname);
append_config_file(mesh, from->name, "ECDSAPublicKey", pubkey);
return true;
}
case REQ_KEY: {
if(!node_read_ecdsa_public_key(mesh, from)) {
- logger(DEBUG_PROTOCOL, LOG_DEBUG, "No ECDSA key known for %s (%s)", from->name, from->hostname);
+ logger(mesh, MESHLINK_DEBUG, "No ECDSA key known for %s (%s)", from->name, from->hostname);
send_request(mesh, from->nexthop->connection, "%d %s %s %d", REQ_KEY, mesh->self->name, from->name, REQ_PUBKEY);
return true;
}
if(from->sptps.label)
- logger(DEBUG_ALWAYS, LOG_DEBUG, "Got REQ_KEY from %s while we already started a SPTPS session!", from->name);
+ logger(mesh, MESHLINK_DEBUG, "Got REQ_KEY from %s while we already started a SPTPS session!", from->name);
char buf[MAX_STRING_SIZE];
int len;
if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS_START", from->name, from->hostname, "invalid SPTPS data");
+ logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s): %s", "REQ_SPTPS_START", from->name, from->hostname, "invalid SPTPS data");
return true;
}
case REQ_SPTPS: {
if(!from->status.validkey) {
- logger(DEBUG_PROTOCOL, LOG_ERR, "Got REQ_SPTPS from %s (%s) but we don't have a valid key yet", from->name, from->hostname);
+ logger(mesh, MESHLINK_ERROR, "Got REQ_SPTPS from %s (%s) but we don't have a valid key yet", from->name, from->hostname);
return true;
}
char buf[MAX_STRING_SIZE];
int len;
if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS", from->name, from->hostname, "invalid SPTPS data");
+ logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s): %s", "REQ_SPTPS", from->name, from->hostname, "invalid SPTPS data");
return true;
}
sptps_receive_data(&from->sptps, buf, len);
}
default:
- logger(DEBUG_ALWAYS, LOG_ERR, "Unknown extended REQ_KEY request from %s (%s): %s", from->name, from->hostname, request);
+ logger(mesh, MESHLINK_ERROR, "Unknown extended REQ_KEY request from %s (%s): %s", from->name, from->hostname, request);
return true;
}
}
int reqno = 0;
if(sscanf(request, "%*d " MAX_STRING " " MAX_STRING " %d", from_name, to_name, &reqno) < 2) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "REQ_KEY", c->name,
+ logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s)", "REQ_KEY", c->name,
c->hostname);
return false;
}
if(!check_id(from_name) || !check_id(to_name)) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_KEY", c->name, c->hostname, "invalid name");
+ logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s): %s", "REQ_KEY", c->name, c->hostname, "invalid name");
return false;
}
from = lookup_node(mesh, from_name);
if(!from) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
+ logger(mesh, MESHLINK_ERROR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
"REQ_KEY", c->name, c->hostname, from_name);
return true;
}
to = lookup_node(mesh, to_name);
if(!to) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
+ logger(mesh, MESHLINK_ERROR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
"REQ_KEY", c->name, c->hostname, to_name);
return true;
}
send_ans_key(mesh, from);
} else {
if(!to->status.reachable) {
- logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
+ logger(mesh, MESHLINK_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
"REQ_KEY", c->name, c->hostname, to_name);
return true;
}
if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d "MAX_STRING" "MAX_STRING,
from_name, to_name, key, &cipher, &digest, &maclength,
&compression, address, port) < 7) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name,
+ logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s)", "ANS_KEY", c->name,
c->hostname);
return false;
}
if(!check_id(from_name) || !check_id(to_name)) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_KEY", c->name, c->hostname, "invalid name");
+ logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s): %s", "ANS_KEY", c->name, c->hostname, "invalid name");
return false;
}
from = lookup_node(mesh, from_name);
if(!from) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
+ logger(mesh, MESHLINK_ERROR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
"ANS_KEY", c->name, c->hostname, from_name);
return true;
}
to = lookup_node(mesh, to_name);
if(!to) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
+ logger(mesh, MESHLINK_ERROR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
"ANS_KEY", c->name, c->hostname, to_name);
return true;
}
if(to != mesh->self) {
if(!to->status.reachable) {
- logger(DEBUG_ALWAYS, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
+ logger(mesh, MESHLINK_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
"ANS_KEY", c->name, c->hostname, to_name);
return true;
}
if(!*address && from->address.sa.sa_family != AF_UNSPEC) {
char *address, *port;
- logger(DEBUG_PROTOCOL, LOG_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name);
+ logger(mesh, MESHLINK_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name);
sockaddr2str(&from->address, &address, &port);
send_request(mesh, to->nexthop->connection, "%s %s %s", request, address, port);
free(address);
from->status.validkey = false;
if(compression < 0 || compression > 11) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
+ logger(mesh, MESHLINK_ERROR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
return true;
}
int len = b64decode(key, buf, strlen(key));
if(!len || !sptps_receive_data(&from->sptps, buf, len))
- logger(DEBUG_ALWAYS, LOG_ERR, "Error processing SPTPS data from %s (%s)", from->name, from->hostname);
+ logger(mesh, MESHLINK_ERROR, "Error processing SPTPS data from %s (%s)", from->name, from->hostname);
if(from->status.validkey) {
if(*address && *port) {
- logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
+ logger(mesh, MESHLINK_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
sockaddr_t sa = str2sockaddr(address, port);
update_node_udp(mesh, from, &sa);
}
char statusstring[MAX_STRING_SIZE];
if(sscanf(request, "%*d %d " MAX_STRING, &statusno, statusstring) != 2) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "STATUS",
+ logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s)", "STATUS",
c->name, c->hostname);
return false;
}
- logger(DEBUG_STATUS, LOG_NOTICE, "Status message from %s (%s): %d: %s",
+ logger(mesh, MESHLINK_INFO, "Status message from %s (%s): %d: %s",
c->name, c->hostname, statusno, statusstring);
return true;
char errorstring[MAX_STRING_SIZE];
if(sscanf(request, "%*d %d " MAX_STRING, &err, errorstring) != 2) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ERROR",
+ logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s)", "ERROR",
c->name, c->hostname);
return false;
}
- logger(DEBUG_ERROR, LOG_NOTICE, "Error message from %s (%s): %d: %s",
+ logger(mesh, MESHLINK_INFO, "Error message from %s (%s): %d: %s",
c->name, c->hostname, err, errorstring);
return false;
short int len;
if(sscanf(request, "%*d %hd", &len) != 1) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "PACKET", c->name,
+ logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s)", "PACKET", c->name,
c->hostname);
return false;
}
static bool checklength(node_t *source, vpn_packet_t *packet, uint16_t length) {
if(packet->len < length) {
- logger(DEBUG_TRAFFIC, LOG_WARNING,
- "Got too short packet from %s (%s)", source->name,
- source->hostname);
+ logger(source->mesh, MESHLINK_WARNING, "Got too short packet from %s (%s)", source->name, source->hostname);
return false;
} else
return true;
node_t *via = NULL;
meshlink_packethdr_t *hdr = (meshlink_packethdr_t *) packet->data;
owner = lookup_node(mesh, (char *)hdr->destination);
- logger(DEBUG_TRAFFIC, LOG_WARNING,
- "Routing packet from: %s . To: %s \n", hdr->source,
- hdr->destination);
+ logger(mesh, MESHLINK_WARNING, "Routing packet from: %s . To: %s \n", hdr->source, hdr->destination);
//Check Lenght
if(!checklength(source, packet, (sizeof(meshlink_packethdr_t))))
if(owner == NULL) {
//Lookup failed
- logger(DEBUG_TRAFFIC, LOG_WARNING, "Cant lookup the owner of a packet in the route() function. This should never happen!\n");
- logger(DEBUG_TRAFFIC, LOG_WARNING, "Destination was: %s\n", hdr->destination);
+ logger(mesh, MESHLINK_WARNING, "Cant lookup the owner of a packet in the route() function. This should never happen!\n");
+ logger(mesh, MESHLINK_WARNING, "Destination was: %s\n", hdr->destination);
return;
}
if(owner == mesh->self) {
- logger(DEBUG_TRAFFIC, LOG_WARNING, "I received a packet for me with payload: %s \n", packet->data + sizeof *hdr);
+ logger(mesh, MESHLINK_WARNING, "I received a packet for me with payload: %s \n", packet->data + sizeof *hdr);
if(mesh->receive_cb)
mesh->receive_cb(mesh, (meshlink_node_t *)source, packet->data + sizeof *hdr, packet->len - sizeof *hdr);
return;
if(!owner->status.reachable) {
//TODO: check what to do here, not just print a warning
- logger(DEBUG_TRAFFIC, LOG_WARNING, "The owner of a packet in the route() function is unreachable. Dropping packet.\n");
+ logger(mesh, MESHLINK_WARNING, "The owner of a packet in the route() function is unreachable. Dropping packet.\n");
return;
}
via = (owner->via == mesh->self) ? owner->nexthop : owner->via;
if(via == source) {
- logger(DEBUG_TRAFFIC, LOG_ERR, "Routing loop for packet from %s (%s)!", source->name, source->hostname);
+ logger(mesh, MESHLINK_ERROR, "Routing loop for packet from %s (%s)!", source->name, source->hostname);
return;
}
// Symbols necessary to link with logger.o
bool send_request(void *c, const char *msg, ...) { return false; }
void *mesh;
+void *global_log_cb;
+int global_log_level;
bool send_meta(void *c, const char *msg , int len) { return false; }
char *logfilename = NULL;
struct timeval now;
// Symbols necessary to link with logger.o
bool send_request(void *c, const char *msg, ...) { return false; }
void *mesh;
+void *global_log_cb;
+int global_log_level;
bool send_meta(void *c, const char *msg , int len) { return false; }
char *logfilename = NULL;
struct timeval now;