]> git.meshlink.io Git - meshlink/blob - src/submesh.c
Ensure we can pass arbitrary binary blobs for keys.
[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 void init_submeshes(meshlink_handle_t *mesh) {
34         mesh->submeshes = list_alloc((list_action_t)free_submesh);
35 }
36
37 void exit_submeshes(meshlink_handle_t *mesh) {
38         if(mesh->submeshes) {
39                 list_delete_list(mesh->submeshes);
40         }
41
42         mesh->submeshes = NULL;
43 }
44
45 submesh_t *new_submesh(void) {
46         submesh_t *s = xzalloc(sizeof(*s));
47
48         s->name = NULL;
49         s->priv = NULL;
50
51         return s;
52 }
53
54 void free_submesh(submesh_t *s) {
55         if(s->name) {
56                 free(s->name);
57         }
58
59         free(s);
60 }
61
62 static submesh_t *submesh_new(meshlink_handle_t *mesh, const char *submesh) {
63         submesh_t *s = NULL;
64
65         s = new_submesh();
66         s->name = xstrdup(submesh);
67
68         submesh_add(mesh, (submesh_t *)s);
69         return s;
70 }
71
72 submesh_t *create_submesh(meshlink_handle_t *mesh, const char *submesh) {
73         submesh_t *s = NULL;
74
75         if(0 == strcmp(submesh, CORE_MESH)) {
76                 logger(NULL, MESHLINK_ERROR, "Cannot create submesh handle for core mesh!\n");
77                 meshlink_errno = MESHLINK_EINVAL;
78                 return NULL;
79         }
80
81         if(!check_id(submesh)) {
82                 logger(NULL, MESHLINK_ERROR, "Invalid SubMesh Id!\n");
83                 meshlink_errno = MESHLINK_EINVAL;
84                 return NULL;
85         }
86
87         s = lookup_submesh(mesh, submesh);
88
89         if(s) {
90                 logger(NULL, MESHLINK_ERROR, "SubMesh Already exists!\n");
91                 meshlink_errno = MESHLINK_EEXIST;
92                 return NULL;
93         }
94
95         s = submesh_new(mesh, submesh);
96
97         meshlink_errno = MESHLINK_OK;
98         return s;
99 }
100
101 submesh_t *lookup_or_create_submesh(meshlink_handle_t *mesh, const char *submesh) {
102         submesh_t *s = NULL;
103
104         if(0 == strcmp(submesh, CORE_MESH)) {
105                 logger(NULL, MESHLINK_ERROR, "Cannot create submesh handle for core mesh!\n");
106                 meshlink_errno = MESHLINK_EINVAL;
107                 return NULL;
108         }
109
110         if(!check_id(submesh)) {
111                 logger(NULL, MESHLINK_ERROR, "Invalid SubMesh Id!\n");
112                 meshlink_errno = MESHLINK_EINVAL;
113                 return NULL;
114         }
115
116         s = lookup_submesh(mesh, submesh);
117
118         if(s) {
119                 meshlink_errno = MESHLINK_OK;
120                 return s;
121         }
122
123         s = submesh_new(mesh, submesh);
124
125         meshlink_errno = MESHLINK_OK;
126         return s;
127 }
128
129 void submesh_add(meshlink_handle_t *mesh, submesh_t *s) {
130         s->mesh = mesh;
131         list_insert_tail(mesh->submeshes, (void *)s);
132 }
133
134 void submesh_del(meshlink_handle_t *mesh, submesh_t *s) {
135         list_delete(mesh->submeshes, (void *)s);
136 }
137
138 submesh_t *lookup_submesh(struct meshlink_handle *mesh, const char *submesh_name) {
139         submesh_t *submesh = NULL;
140
141         if(!mesh->submeshes) {
142                 return NULL;
143         }
144
145         for list_each(submesh_t, s, mesh->submeshes) {
146                 if(!strcmp(submesh_name, s->name)) {
147                         submesh = s;
148                         break;
149                 }
150         }
151
152         return submesh;
153 }
154
155 bool submesh_allows_node(const submesh_t *submesh, const node_t *node) {
156         if(!node->submesh || !submesh || submesh == node->submesh) {
157                 return true;
158         } else {
159                 return false;
160         }
161 }