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