]> git.meshlink.io Git - meshlink/blob - src/submesh.c
Use multicast to respond to mDNS requests.
[meshlink] / src / submesh.c
1 /*
2     submesh.c -- submesh management
3     Copyright (C) 2019 Guus Sliepen <guus@meshlink.io>,
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License along
16     with this program; if not, write to the Free Software Foundation, Inc.,
17     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "system.h"
21
22 #include "hash.h"
23 #include "logger.h"
24 #include "meshlink_internal.h"
25 #include "net.h"
26 #include "netutl.h"
27 #include "submesh.h"
28 #include "splay_tree.h"
29 #include "utils.h"
30 #include "xalloc.h"
31 #include "protocol.h"
32
33 static submesh_t *new_submesh(void) {
34         return xzalloc(sizeof(submesh_t));
35 }
36
37 static void free_submesh(submesh_t *s) {
38         free(s->name);
39         free(s);
40 }
41
42 void init_submeshes(meshlink_handle_t *mesh) {
43         assert(!mesh->submeshes);
44         mesh->submeshes = list_alloc((list_action_t)free_submesh);
45 }
46
47 void exit_submeshes(meshlink_handle_t *mesh) {
48         if(mesh->submeshes) {
49                 list_delete_list(mesh->submeshes);
50         }
51
52         mesh->submeshes = NULL;
53 }
54
55 static submesh_t *submesh_add(meshlink_handle_t *mesh, const char *submesh) {
56         assert(submesh);
57
58         submesh_t *s = new_submesh();
59         s->name = xstrdup(submesh);
60         list_insert_tail(mesh->submeshes, (void *)s);
61         return s;
62 }
63
64 submesh_t *create_submesh(meshlink_handle_t *mesh, const char *submesh) {
65         assert(submesh);
66
67         if(0 == strcmp(submesh, CORE_MESH)) {
68                 logger(NULL, MESHLINK_ERROR, "Cannot create submesh handle for core mesh!\n");
69                 meshlink_errno = MESHLINK_EINVAL;
70                 return NULL;
71         }
72
73         if(!check_id(submesh)) {
74                 logger(NULL, MESHLINK_ERROR, "Invalid SubMesh Id!\n");
75                 meshlink_errno = MESHLINK_EINVAL;
76                 return NULL;
77         }
78
79         if(lookup_submesh(mesh, submesh)) {
80                 logger(NULL, MESHLINK_ERROR, "SubMesh Already exists!\n");
81                 meshlink_errno = MESHLINK_EEXIST;
82                 return NULL;
83         }
84
85         return submesh_add(mesh, submesh);
86 }
87
88 submesh_t *lookup_or_create_submesh(meshlink_handle_t *mesh, const char *submesh) {
89         assert(submesh);
90
91         if(0 == strcmp(submesh, CORE_MESH)) {
92                 logger(NULL, MESHLINK_ERROR, "Cannot create submesh handle for core mesh!\n");
93                 meshlink_errno = MESHLINK_EINVAL;
94                 return NULL;
95         }
96
97         if(!check_id(submesh)) {
98                 logger(NULL, MESHLINK_ERROR, "Invalid SubMesh Id!\n");
99                 meshlink_errno = MESHLINK_EINVAL;
100                 return NULL;
101         }
102
103         submesh_t *s = lookup_submesh(mesh, submesh);
104
105         if(s) {
106                 meshlink_errno = MESHLINK_OK;
107                 return s;
108         }
109
110         return submesh_add(mesh, submesh);
111 }
112
113 submesh_t *lookup_submesh(struct meshlink_handle *mesh, const char *submesh_name) {
114         assert(submesh_name);
115
116         submesh_t *submesh = NULL;
117
118         if(!mesh->submeshes) {
119                 return NULL;
120         }
121
122         for list_each(submesh_t, s, mesh->submeshes) {
123                 if(!strcmp(submesh_name, s->name)) {
124                         submesh = s;
125                         break;
126                 }
127         }
128
129         return submesh;
130 }
131
132 bool submesh_allows_node(const submesh_t *submesh, const node_t *node) {
133         if(!node->submesh || !submesh || submesh == node->submesh) {
134                 return true;
135         } else {
136                 return false;
137         }
138 }