Coverage Report

Created: 2024-02-29 06:05

/src/strongswan/src/libstrongswan/networking/streams/stream_manager.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2013 Martin Willi
3
 *
4
 * Copyright (C) secunet Security Networks AG
5
 *
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by the
8
 * Free Software Foundation; either version 2 of the License, or (at your
9
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
10
 *
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * for more details.
15
 */
16
17
#include "stream_manager.h"
18
19
#include "stream_tcp.h"
20
#include "stream_service_tcp.h"
21
#ifndef WIN32
22
# include "stream_unix.h"
23
# include "stream_service_unix.h"
24
#endif
25
#ifdef USE_SYSTEMD
26
# include "stream_service_systemd.h"
27
#endif
28
29
#include <threading/rwlock.h>
30
31
typedef struct private_stream_manager_t private_stream_manager_t;
32
33
/**
34
 * Private data of an stream_manager_t object.
35
 */
36
struct private_stream_manager_t {
37
38
  /**
39
   * Public stream_manager_t interface.
40
   */
41
  stream_manager_t public;
42
43
  /**
44
   * List of registered stream constructors, as stream_entry_t
45
   */
46
  linked_list_t *streams;
47
48
  /**
49
   * List of registered service constructors, as service_entry_t
50
   */
51
  linked_list_t *services;
52
53
  /**
54
   * Lock for all lists
55
   */
56
  rwlock_t *lock;
57
};
58
59
/**
60
 * Registered stream backend
61
 */
62
typedef struct {
63
  /** URI prefix */
64
  char *prefix;
65
  /** constructor function */
66
  stream_constructor_t create;
67
} stream_entry_t;
68
69
/**
70
 * Registered service backend
71
 */
72
typedef struct {
73
  /** URI prefix */
74
  char *prefix;
75
  /** constructor function */
76
  stream_service_constructor_t create;
77
} service_entry_t;
78
79
METHOD(stream_manager_t, connect_, stream_t*,
80
  private_stream_manager_t *this, char *uri)
81
0
{
82
0
  enumerator_t *enumerator;
83
0
  stream_entry_t *entry;
84
0
  stream_t *stream = NULL;
85
86
0
  this->lock->read_lock(this->lock);
87
0
  enumerator = this->streams->create_enumerator(this->streams);
88
0
  while (enumerator->enumerate(enumerator, &entry))
89
0
  {
90
0
    if (strpfx(uri, entry->prefix))
91
0
    {
92
0
      stream = entry->create(uri);
93
0
      if (stream)
94
0
      {
95
0
        break;
96
0
      }
97
0
    }
98
0
  }
99
0
  enumerator->destroy(enumerator);
100
0
  this->lock->unlock(this->lock);
101
102
0
  return stream;
103
0
}
104
105
METHOD(stream_manager_t, create_service, stream_service_t*,
106
  private_stream_manager_t *this, char *uri, int backlog)
107
0
{
108
0
  enumerator_t *enumerator;
109
0
  service_entry_t *entry;
110
0
  stream_service_t *service = NULL;
111
112
0
  this->lock->read_lock(this->lock);
113
0
  enumerator = this->services->create_enumerator(this->services);
114
0
  while (enumerator->enumerate(enumerator, &entry))
115
0
  {
116
0
    if (strpfx(uri, entry->prefix))
117
0
    {
118
0
      service = entry->create(uri, backlog);
119
0
      if (service)
120
0
      {
121
0
        break;
122
0
      }
123
0
    }
124
0
  }
125
0
  enumerator->destroy(enumerator);
126
0
  this->lock->unlock(this->lock);
127
128
0
  return service;
129
0
}
130
131
METHOD(stream_manager_t, add_stream, void,
132
  private_stream_manager_t *this, char *prefix, stream_constructor_t create)
133
7.84k
{
134
7.84k
  stream_entry_t *entry;
135
136
7.84k
  INIT(entry,
137
7.84k
    .prefix = strdup(prefix),
138
7.84k
    .create = create,
139
7.84k
  );
140
141
7.84k
  this->lock->write_lock(this->lock);
142
7.84k
  this->streams->insert_last(this->streams, entry);
143
7.84k
  this->lock->unlock(this->lock);
144
7.84k
}
145
146
METHOD(stream_manager_t, remove_stream, void,
147
  private_stream_manager_t *this, stream_constructor_t create)
148
7.84k
{
149
7.84k
  enumerator_t *enumerator;
150
7.84k
  stream_entry_t *entry;
151
152
7.84k
  this->lock->write_lock(this->lock);
153
7.84k
  enumerator = this->streams->create_enumerator(this->streams);
154
19.6k
  while (enumerator->enumerate(enumerator, &entry))
155
11.7k
  {
156
11.7k
    if (entry->create == create)
157
7.84k
    {
158
7.84k
      this->streams->remove_at(this->streams, enumerator);
159
7.84k
      free(entry->prefix);
160
7.84k
      free(entry);
161
7.84k
    }
162
11.7k
  }
163
7.84k
  enumerator->destroy(enumerator);
164
7.84k
  this->lock->unlock(this->lock);
165
7.84k
}
166
167
METHOD(stream_manager_t, add_service, void,
168
  private_stream_manager_t *this, char *prefix,
169
  stream_service_constructor_t create)
170
7.84k
{
171
7.84k
  service_entry_t *entry;
172
173
7.84k
  INIT(entry,
174
7.84k
    .prefix = strdup(prefix),
175
7.84k
    .create = create,
176
7.84k
  );
177
178
7.84k
  this->lock->write_lock(this->lock);
179
7.84k
  this->services->insert_last(this->services, entry);
180
7.84k
  this->lock->unlock(this->lock);
181
7.84k
}
182
183
METHOD(stream_manager_t, remove_service, void,
184
  private_stream_manager_t *this, stream_service_constructor_t create)
185
7.84k
{
186
7.84k
  enumerator_t *enumerator;
187
7.84k
  service_entry_t *entry;
188
189
7.84k
  this->lock->write_lock(this->lock);
190
7.84k
  enumerator = this->services->create_enumerator(this->services);
191
19.6k
  while (enumerator->enumerate(enumerator, &entry))
192
11.7k
  {
193
11.7k
    if (entry->create == create)
194
7.84k
    {
195
7.84k
      this->services->remove_at(this->services, enumerator);
196
7.84k
      free(entry->prefix);
197
7.84k
      free(entry);
198
7.84k
    }
199
11.7k
  }
200
7.84k
  enumerator->destroy(enumerator);
201
7.84k
  this->lock->unlock(this->lock);
202
7.84k
}
203
204
METHOD(stream_manager_t, destroy, void,
205
  private_stream_manager_t *this)
206
3.92k
{
207
3.92k
  remove_stream(this, stream_create_tcp);
208
3.92k
  remove_service(this, stream_service_create_tcp);
209
3.92k
#ifndef WIN32
210
3.92k
  remove_stream(this, stream_create_unix);
211
3.92k
  remove_service(this, stream_service_create_unix);
212
3.92k
#endif
213
#ifdef USE_SYSTEMD
214
  remove_service(this, stream_service_create_systemd);
215
#endif
216
217
3.92k
  this->streams->destroy(this->streams);
218
3.92k
  this->services->destroy(this->services);
219
3.92k
  this->lock->destroy(this->lock);
220
3.92k
  free(this);
221
3.92k
}
222
223
/**
224
 * See header
225
 */
226
stream_manager_t *stream_manager_create()
227
3.92k
{
228
3.92k
  private_stream_manager_t *this;
229
230
3.92k
  INIT(this,
231
3.92k
    .public = {
232
3.92k
      .connect = _connect_,
233
3.92k
      .create_service = _create_service,
234
3.92k
      .add_stream = _add_stream,
235
3.92k
      .remove_stream = _remove_stream,
236
3.92k
      .add_service = _add_service,
237
3.92k
      .remove_service = _remove_service,
238
3.92k
      .destroy = _destroy,
239
3.92k
    },
240
3.92k
    .streams = linked_list_create(),
241
3.92k
    .services = linked_list_create(),
242
3.92k
    .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
243
3.92k
  );
244
245
3.92k
  add_stream(this, "tcp://", stream_create_tcp);
246
3.92k
  add_service(this, "tcp://", stream_service_create_tcp);
247
3.92k
#ifndef WIN32
248
3.92k
  add_stream(this, "unix://", stream_create_unix);
249
3.92k
  add_service(this, "unix://", stream_service_create_unix);
250
3.92k
#endif
251
#ifdef USE_SYSTEMD
252
  add_service(this, "systemd://", stream_service_create_systemd);
253
#endif
254
255
3.92k
  return &this->public;
256
3.92k
}