+ }
+ }
+
+ return tmin;
+}
+
+// Get our local address(es) by simulating connecting to an Internet host.
+static void add_local_addresses(meshlink_handle_t *mesh) {
+ char host[NI_MAXHOST];
+ char entry[MAX_STRING_SIZE];
+
+ // IPv4 example.org
+
+ if(getlocaladdrname("93.184.216.34", host, sizeof(host), mesh->netns)) {
+ snprintf(entry, sizeof(entry), "%s %s", host, mesh->myport);
+ append_config_file(mesh, mesh->name, "Address", entry);
+ }
+
+ // IPv6 example.org
+
+ if(getlocaladdrname("2606:2800:220:1:248:1893:25c8:1946", host, sizeof(host), mesh->netns)) {
+ snprintf(entry, sizeof(entry), "%s %s", host, mesh->myport);
+ append_config_file(mesh, mesh->name, "Address", entry);
+ }
+}
+
+static bool meshlink_setup(meshlink_handle_t *mesh) {
+ if(mkdir(mesh->confbase, 0777) && errno != EEXIST) {
+ logger(mesh, MESHLINK_DEBUG, "Could not create directory %s: %s\n", mesh->confbase, strerror(errno));
+ meshlink_errno = MESHLINK_ESTORAGE;
+ return false;
+ }
+
+ char filename[PATH_MAX];
+ snprintf(filename, sizeof(filename), "%s" SLASH "hosts", mesh->confbase);
+
+ if(mkdir(filename, 0777) && errno != EEXIST) {
+ 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)) {
+ logger(mesh, MESHLINK_DEBUG, "Configuration file %s already exists!\n", filename);
+ meshlink_errno = MESHLINK_EEXIST;
+ return false;
+ }
+
+ FILE *f = fopen(filename, "w");
+
+ if(!f) {
+ logger(mesh, MESHLINK_DEBUG, "Could not create file %s: %s\n", filename, strerror(errno));
+ meshlink_errno = MESHLINK_ESTORAGE;
+ return false;
+ }
+
+ fprintf(f, "Name = %s\n", mesh->name);
+ fclose(f);
+
+ if(!ecdsa_keygen(mesh)) {
+ meshlink_errno = MESHLINK_EINTERNAL;
+ unlink(filename);
+ return false;
+ }
+
+ if(check_port(mesh) == 0) {
+ meshlink_errno = MESHLINK_ENETWORK;
+ unlink(filename);
+ return false;
+ }
+
+ return true;
+}
+
+static void *setup_network_in_netns_thread(void *arg) {
+ meshlink_handle_t *mesh = arg;
+
+ if(setns(mesh->netns, CLONE_NEWNET) != 0) {
+ return NULL;
+ }
+
+ bool success = setup_network(mesh);
+ add_local_addresses(mesh);
+ return success ? arg : NULL;
+}
+
+meshlink_open_params_t *meshlink_open_params_init(const char *confbase, const char *name, const char *appname, dev_class_t devclass) {
+ if(!confbase || !*confbase) {
+ logger(NULL, MESHLINK_ERROR, "No confbase given!\n");
+ meshlink_errno = MESHLINK_EINVAL;
+ return NULL;
+ }
+
+ if(!appname || !*appname) {
+ logger(NULL, MESHLINK_ERROR, "No appname given!\n");
+ meshlink_errno = MESHLINK_EINVAL;
+ return NULL;
+ }
+
+ if(strchr(appname, ' ')) {
+ logger(NULL, MESHLINK_ERROR, "Invalid appname given!\n");
+ meshlink_errno = MESHLINK_EINVAL;
+ return NULL;
+ }
+
+ if(!name || !*name) {
+ logger(NULL, MESHLINK_ERROR, "No name given!\n");
+ //return NULL;
+ } else { //check name only if there is a name != NULL
+ if(!check_id(name)) {
+ logger(NULL, MESHLINK_ERROR, "Invalid name given!\n");
+ meshlink_errno = MESHLINK_EINVAL;
+ return NULL;
+ }